前言:
vue2
的双向数据绑定是利⽤ES5
的⼀个 API ,Object.defineProperty( )
对数据进行劫持结合发布订阅模式的方式来实现的。
vue3
中使⽤了 ES6
的Proxy
代理对象,通过 reactive()
函数给每⼀个对象都包⼀层Proxy
,通过 Proxy
监听属性的变化,从而实现对数据的代理操作。
一,Object.defineProperty( )
let obj = { }
let val = ''
Object.defineProperty(obj,'name',{
enumerable: true, // 表示该属性是否可以在 for...in 循环中被枚举。默认为 false。
configurable: true, // 能否被删除 默认false
get(){
console.log(`访问name属性`)
return val
},
set(newVal){
console.log('newVal',newVal);
val = newVal
}
})
obj.name = 'coderkey' // 触发set方法
console.log(obj.name); // 触发get方法
obj.age = '18' // 不会触发set方案
console.log(obj.age); // 不会触发get方法
delete obj.name; // 不会触发set方案
注意:只能访问和修改,新增和删除不会触发set方法
二,Proxy代理对象
let obj = {
name: 'coderkey',
age: 18,
habby: {
try1: '篮球鸡坤',
try2: '足球'
}
}
let handler = {
// 访问
get(target, prop) {
console.log('触发get方法',target[prop]);
return Reflect.get(target, prop)
},
// 修改与新增
set(target, prop, value) {
console.log('触发set方法',value);
//通过反射对象把数据反射出去
return Reflect.set(target, prop, value)
},
// 删除
deleteProperty(target, prop) {
console.log('触发delete方法');
return Reflect.set(target, prop)
}
}
let proxyObj = new Proxy(obj,handler)
// 通过代理对象对目标对象进行增删改查操作
proxyObj.name = 'pink' // 触发set方法
proxyObj.sex = '男' // 触发set方法
console.log(proxyObj.sex); // 触发get方法
delete proxyObj.sex // 触发deleteProperty方法
console.log(proxyObj.sex); // 触发get方法 undefined
console.log(proxyObj); // 代理对象 {name: 'pink', age: 18, sex: undefined}
注意: 可以代理同一层对象,可以增删改查操作