在vue2和vue3中对于data数据的劫持分别用了不同的方法。 下面使用一个小例子进行说明: 当name变化时,希望fullName也发生变化。
vue2 -> Object.defineProperty
const data = {
_name: 'phoeny',
fullName: 'phoeny Wu',
}
// 使用Object.defineProperty定义name属性,在它的setter方法中设置改变fullName属性
Object.defineProperty(data, 'name', {
configurable: true,
enumerable: true,
get() {
return data._name
},
set(value) {
data.fullName = value + ' Wu';
data._name = value
}
})
data.name = 'sycamore';
console.log(data.fullName)
vue3 -> Proxy
const data = {
name: 'phoeny',
fullName: 'phoeny Wu',
};
const handler = {
set(target, key, value, receiver) {
if (key === 'name') {
// 我们可以像下面注释掉的代码一样,直接改变target的属性,也可以使用配套的Reflect对象对target的底层操作进行覆写
Reflect.set(target, 'fullName', value + ' Wu', receiver)
// target.fullName = value + ' Wu';
}
// 如果缺少这一句,那么就只改了fullname的值,而没有改变name的值
Reflect.set(target, key, value, receiver)
// target.name = value
},
};
// proxy 接受两个参数,第一个是需要代理的目标对象,第二个是可以拦截目标底层操作的对象
// 每个js对象都有很多底层操作,常见的有get/set/has...
// 在第二个参数对象中可以对这些底层操作进行拦截,比如对set进行拦截,就可以实现当改变某个值的时候,其他的值一起变化的效果。
const proxy = new Proxy(data, handler);
proxy.name = 'sycamore';
console.log(data.fullName) // sycamore Wu