携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
喜欢就点个赞吧🎈😊
🎉 前言
这里我们来比较一下Vue 和Vue3的响应式数据的原理。在Vue2中使用的是Object.defineProperty.而在Vue3中使用的是Proxy代理的方式。一下我们将对这两者之间进行比较。
🎉 Vue2的数据劫持的弊端
这是由于Object.defineProperty这是提供了两个方法一个是个get,另一个是set。只有当获取或者修改的时候才可以进行数据的劫持。
- 新增属性、删除属性页面不会发生变化。
解决方法使用组件中的$set(对象,属性名,属性值)进行设置或者直接用Vue.set();使用组件中的$delete(属性名,属性值)进行设置或者直接用Vue.delete();
- 直接通过下标修改数组,界面也不会发生变化。
解决方法:使用组件中的$set(对象,属性名,属性值)进行设置或者直接用Vue.set();使用组件中的$delete(属性名,属性值)进行设置或者直接用Vue.delete();或者通过调用Vue二次封装的数组的方法。splice()来进行下标值得替换。
//Vue2的响应式原理
let person = {
name:'张三',
age = 10
}
let p = {}
Object.defineProperty(p, 'name',{
configurable:true //可删除的
enumerable: true//可枚举的
writable:true//可修改的
get(){
return person.name
}
set(value){}
person.name = value
})
🎉 Vue3的响应式原理
🎇 window.Proxy内置的构造函数
🎇Vue3中的实现方式
- 通过Proxy (代理)︰拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等。
- 通过Reflect(反射)︰对源对象的属性进行操作。
🎉 Vue3中的reactive和ref
🎇 定义方面
- ref用来定义:基本类型数据。
- reactive用来定义:对象(或数组)类型数据。
- 备注: ref也可以用来定义对象(或数组)类型数据,它内部会自动通过 reactive转为代理对象。
🎇 原理方面
- ref通过object.defineProperty()的get与set来实现响应式(数据劫持)。
- reactive通过使用Proxy来实现响应式(数据劫持)﹐并通过Reflect操作源对象内部的数据。
🎇 使用方面
- ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value
- reactive定义的数据:操作数据与读取数据:均不需要.value。
🎉 Vue3中的setup
在Vue3中, 要将所有的东西写到setup(){}中。
export default {
name: 'App',
// setup返回一个对象,则对象的属性方法在模板上均有体现
setup() {
//响应式数据
//在vue3中使用ref 使用会生成一个RefImpl引用实例对象,实现的方法也是 Object.defineProperty
let name = ref('张三')
let person = reactive({
name: "李四",
age: 20,
hobbies: ['抽烟', '喝酒', '烫头']
})
//方法
function sayHello() {
alert(`${name}这是我的名字 `)
}
function sayName() {
alert(person.name)
}
return {
name,
sayHello,
person,
sayName
}
}
}
🎇 注意点
- 在beforeCreate之前执行一次,this是undefined。
- setup的参数
- props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
- context: 上下文对象
- attrs:值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,this.$attrs
- slots: 收到的插槽内容,相当于this.$slots 。
- emit:分发自定义事件的函数,相当于|this.$emit]。