vue2
通俗原理: 通过Object.defineProperty() 进行数据劫持的同时, 收集关联影响。比如发现响应式数据时,收集相关geter setter 的影响,(通过订阅发布模式触发render 渲染)如果有影响,对比更新虚拟dom Tree 重新渲染)
1.Object.defineProperty()定义对象属性特征
// Object.defineProperty(对象,属性名, 属性描述)
const obj = {}
// 通过此方式进行数据劫持
Object.defineProperty(obj, 'name', {
value: '属性值',
writable: true, // 是否可写
enumerable: true, // 是否可枚举
})
console.log(obj.name) // 属性值
2. Object.defineProperty() 的get()和set()
const obj = {
}
const obj2 = Object.create(obj) // 继承 obj 对象
// 通过此方式进行数据劫持
Object.defineProperty(obj,'age', {
// value: '属性值', 不能与get set 同时出现
// writable: true, // 是否可写 不能与get set 同时出现
// enumerable: true, // 是否可枚举
get() {
console.log('get')
return value
},
set(nVal) {
console.log('set');
value = nVal
}
})
obj.age = 88
console.log(obj.age) // 属性值
vue3 中的proxy基本用法
通俗原理: (同v2相似)通过Proxy(好处:支持 Map Set) 进行数据劫持的同时, 收集副作用。比如发现响应式数据时,收集相关geter setter 的影响,(通过订阅发布模式触发render 渲染)如果有影响,对比更新虚拟dom Tree 重新渲染)
const obj = {}
const proxyObj = new Proxy(obj, {
get(target, key, receiver) {
console.log('get 收集effect');
if (key in target) {
return target[key] || Reflect.get(target, key)
} else {
throw new ReferenceError(`${key}不存在,抓不到它`)
}
},
set(target, key, value, receiver) { // 4个参数 target, key, value, receiver
console.log('set触发 收集effect')
console.log(receiver === obj) // false
console.log(receiver === proxyObj) // true
// target[key] = value
return Reflect.set(target, key, value) // 源码通过 Reflect进行操作后返回一个布尔值
}
})
proxyObj.name = 'lllll'
console.log(proxyObj.name)