1. vue2和vue3区别
vue2和vue3双向绑定的方法不同
vue2:Object.defineProperty——>后添加的属性劫持不到——>因此用到了$set来解决数据更新了但视图没更新的问题
vue3: new Proxy——>即使是后添加的属性,也可以劫持到——>vue3中没有$set,因为不需要
/* vue3中的双向绑定 */
<script>
let data = {
a: 1,
b: 2
}
let vue = new Proxy(data,{
get( target, propKey, receiver ){
console.log('获取了');
return Reflect.get(target, propKey, receiver);
},
set( target, propKey, value, receiver ){
console.log('设置了');
return Reflect.set(target, propKey, value, receiver);
}
})
vue.c = 3
console.log(vue.c)
</script>
/* vue2中的双向绑定 */
<script>
let data = {
a: 1,
b: 2
}
let vue = {};
for( let k in data ){
Object.defineProperty(vue,k,{
get(){
console.log('获取了')
return data[k]
}.
set(value){
console.log('设置了');
data[k] = value;
}
})
}
vue.a = '11111'
console.log(vue)
vue.c = 3
console.log(vue)
</script>
vue2是选项式API,vue3可以向下兼容,既可以是选项式API,也可以是组合式API或setup语法糖的形式
vue2中v-for的优先级大于v-if,vue3中v-if的优先级大于v-for
2. vue3的hooks
hooks就是函数式,主要是用来将功能模块细分(提升项目的维护性)
3. vue3如果用setup写,如何获取类似于vue2中的this
可以利用getCurrentInstance
<script>
import { getCurrentInstance } from 'vue'
let app = getCurrentInstance();
console.log( app )
</script>
4. vue3常用的API有哪些
createApp()——>创建一个应用实例,等于vue2中的new Vue(),写插件(封装全局组件)的时候会用到;
provide/inject——>依赖注入,其实就是传值,某一个父组件传值到后代组件,如果层级过多传递麻烦的时候使用,缺点是不好维护以及不好查询数据来源;
directive——>自定义指令,后台管理系统中的按钮控制权限(比如某个用户它只有查看和修改的权限,没有删除的权限);
mixin——>全局混入,可以用于添加生命周期,小程序的分享功能会用到,缺点是不好维护和查询数据来源;
app.config.globalProperties——>获取vue这个全局对象的属性和方法,自己封装插件的时候需要把方法添加到对象中;
nextTick——>等待下一次DOM更新的工具方法,nextTick返回的是一个Promise,回调函数是放在Promise中的,所以是异步执行的;
computed——>计算属性,有缓存
reactive,ref——>用来定义数据的,跟vue2的data类似
watch——>用于监听(vue3不需要深度监听)
markRaw——>不被new Proxy代理,说白了就是静态的数据
defineProps()——>父组件传递的值,子组件使用setup的形式,需要用defineProps接收
defineEmits()——>当前组件使用setup形式,自定义事件需要使用defineEmits
slot——>分为匿名,具名,作用域,比如说后台管理系统,左侧菜单是固定菜单,右侧是不固定内容,那么右侧就是slot
5. vue3常用的响应式数据类型
ref,reactive,toRef,toRefs
/* 这个点击后sum值并不会变(不是响应式的) */
<template>
<div>
{{ sum }}
<button @click='btn'>按钮</button>
</div>
</template>
<script>
let sum = 10;
const btn = () => {
sum = 20
}
</script>
/* 这个点击后sum值会变(改成响应式的) */
<template>
<div>
{{ sum }} {{ obj }} {{ obj.name }} {{ name }}
<button @click='btn'>按钮</button>
</div>
</template>
<script>
import { ref, reactive, toRef, toRefs } from 'vue'
let sum = ref(10); // 定义基本的数据类型一般用ref
let obj = reactive({ // 定义复杂的数据类型一般用reactive
name: '张三',
age: 18,
sex: '男'
});
let name = toRef(obj, 'name'); // 可以利用toRef把name解构出来(如果觉得写obj.name麻烦的话)
let {age, sex} = toRefs(obj); // 如果想要解构一个以上的属性,可以使用toRefs
const btn = () => {
sum.value = 20;
obj.name = '李四'
}
</script>
6. teleport组件(传送门)及其使用场景
在做弹出框的时候,想要把弹出框在整个页面居中的时候会用到
假设页面中,有一个点击按钮D和一个组件A,其中组件A里面有两个子组件A,B,它们分别占组件A大小的1/3和2/3,然后在组件B里面有一个弹框,点击按钮D的时候就会弹出这个弹框(该弹框设置了一个相对居中的样式)。
默认情况下,弹出的弹框会在B组件的页面中(也就是2/3的这块)水平垂直居中,但是现在我们想要在A组件这个大的父组件中居中,就可以用到teleport将弹出框传送到body中。
<temport to='body' >
<div>我是弹出框</div>
</temport>