setup的使用
setup是Vue3与Vue2不同的一点,不同于Vue2中需要将响应式数据与函数等分开写,Vue3中数据、方法都可以写在setup中。Vue3也可以使用Vue2中的写法。
使用setup之后更加方便,但是数据不再是响应式的数据了,需要使用ref函数
ref函数
引入: import { ref } from 'vue'
使用: let name = ref('mhc');
let person = ref({
age:20,
salary:0
})
修改: name.value = 'mhc'
person.value.age = 21
也就是说Vue3同样有get()和set()方法,但是是放到了原型上,这样做可以使 查看数据时更加干净,但是又能使用getset方法。
Vue3中,基本类型的数据的响应式依旧是靠Object.defineProperty()来实现的,但是对象类型的数据则是依靠Vue3中的一个名为reactive的新函数实现的
reactive函数
●作用:定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
●语法: const代理对象= reactive(源对象) 接收一个对象(或数组),返回一个代理对象(proxy对象)
●reactive定 义的响应式数据是‘深层次的"。
●内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作。
reactive函数与ref函数不同:reactive函数由于是使用proxy代理的,因此修改的时候不必再像之前那样name.value=‘mhc’去修改,可以直接person.age = 21这样式去修改
Vue3.0的响应式
●实现原理:
●通过Proxy (代理) : 拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等。
●通过Reflect (反射) :对被代理对象的属性进行操作。
proxy是window上自带的构造函数
const p = new Proxy(person,{
get(target,propName){ //target是原对象,即传入的person,propName是要操作的对象的名称
return target[propName];
},
set(target,propName,value){
更新的函数
}
})
Vue2响应式的缺陷
无法捕获到对数据的添加和删除,也就是我通过函数添加一些新的属性的时候,或者是删除原先的属性的时候,响应式会出问题
Reflect与Object的区别
Reflect的写法和object一样,但是与Object不同的是Reflect有一个返回值,代表此次操作是否成功,而Object没有,这就导致当有一段代码写错了时,Object会卡死,但是Reflect可以运行下去。
实现同样的功能,用Object写的脚手架需要更复杂的语句来保证代码的健壮性。
reactive对比ref
●从定义数据角度对比:
。ref用来定义:基本类型数据。
。reactive用来定义: 对象(或数组)类型数据。
。备注: ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象。
●从原理角度对比:
。ref通过object.defineProperty()的get与set来实现响应式(数据劫持)。
。reactive通过使用Proxy来实现响应式(数据劫持) , 并通过Reflect操作源对象内部的数据。
●从使用角度对比:
。ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。
。reactive定 义的数据:操作数据与读取数据:均不需要.value。
setup的两个注意点
●setup执行的时机
。在beforeCreate之 前执行一次, this是undefined.
●setup的参数
。props: 值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
。context: 上下文对象
■attrs:值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于this . $attrs。
■slots: 收到的插槽内容,相当于this. $slots 。
■lemit: 分发自定义事件的函数, 相当于this .$emit 。