一般自己的学习笔记都放在备忘录里吃灰了,今天有时间就来整理一下vue2和vue3实现数据绑定他原理的不同之处。
如果一句话总结那就是 vue2实现的原理是依赖于Object.defineProperty,而vue3依赖的是Proxy
Object.defineProperty
这个方法能直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。而vue2中正式通过这种方式来实现的响应式数据
但是对于这种普通的属性还好,对于数组和对象的监听都需要重新封装,而对于复杂的对象进行深度监听就需要不断的的递归 因此他就存在一些缺点:
1、深度监听,需要递归到底,一次性计算量大
2、无法监听新增属性/删除属性(vue.set 和vue.delete)
因此vue3就使用了proxy实现响应式
Proxy
可以用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
要记得proxy和reflect搭配,他们俩刚好是一一对应的关系
const proxyData = new Proxy(data, {
get(target, key, receiver) {
// 只处理本身(非原型的)属性
const ownKeys = Reflect.ownKeys(target)
if (ownKeys.includes(key)) {
console.log('get', key) // 监听
}
const result = Reflect.get(target, key, receiver)
return result // 返回结果
},
set(target, key, val, receiver) {
// 重复的数据,不处理
if (val === target[key]) {
return true
}
const result = Reflect.set(target, key, val, receiver)
console.log('set', key, val)
// console.log('result', result) // true
return result // 是否设置成功
},
deleteProperty(target, key) {
const result = Reflect.deleteProperty(target, key)
console.log('delete property', key)
// console.log('result', result) // true
return result // 是否删除成功
}
})
那么相比之下proxy的好处:
1、提高了性能,以前是上来就要深度监听,现在是触发到了才会监听
2、可监听新增/删除属性
3、可监听数组
它能够规避object.defineProperty的问题,但是无法兼容所有的浏览器,这也是他的一个弊端,至于哪些不兼容大家可以去can i use网站自己自行搜索各种属性方法的兼容性