vue2响应式
Object.defineProperty
- 不能监听到新增或删除属性
let obj = {
name: 'cjc',
age: 999
}
Object.keys(obj).forEach(key => {
let value = obj[key]
Object.defineProperty(obj, key, {
get() {
console.log('获取值');
return value
},
set(newVal) {
console.log('设置值');
value = newVal
}
})
})
console.log('打印', obj.name);
obj.name = 'CCC'
console.log('打印', obj.name);
// 获取值
// 打印 cjc
// 设置值
// 获取值
// 打印 CCC
vue3响应式
proxy
let obj = {
name: 'cjc',
age: 999
}
const proxyObj = new Proxy(obj, {
get(target,property,receiver) {
console.log('获取值');
return target[property]
},
set(target,property,newValue,receiver) {
console.log('设置值');
target[property] = newValue
},
deleteProperty(target,property){
console.log(`删除属性${property}`);
delete target[property]
}
})
console.log('打印', proxyObj.name);
proxyObj.name = 'CCC'
console.log('打印', proxyObj.name);
delete proxyObj.age
// 获取值
// 打印 cjc
// 设置值
// 获取值
// 打印 CCC
// 删除属性age
new Proxy(target, handler)
handler对象所有的捕获器:
Reflect对象
Reflect对象和Object有些方法相似,是为了替代早期Object的方法
let obj = {
name: 'cjc',
age: 999
}
console.log(Object.keys(obj));
// 同delete obj,不过Reflect.deleteProperty有返回值
console.log(Reflect.deleteProperty(obj,'age'));
console.log(Object.keys(obj));
proxy和Reflect结合使用
- 代理目的:不直接操作原对象
- Reflect对象的方法有返回值,便于判断
- receiver为当前的proxy对象,Reflect的get/set方法最后一个参数决定setter/getter的this指向
let obj = {
// 私有属性
_name: 'cjc',
set name(newValue) {
// this默认指向obj
console.log('this:', this);
this._name = newValue
},
get name() {
return this._name
}
}
const proxyObj = new Proxy(obj, {
set(target, property, newValue, receiver) {
console.log('proxy设置值');
const flag = Reflect.set(target, property, newValue, receiver)
if (!flag) throw new Error()
},
get(target, property, receiver) {
console.log('proxy获取值');
return Reflect.get(target, property, receiver)
}
})
console.log(proxyObj.name);