vue2.0是的数据响应式是基于Object.defineProperty的方式来实现的,到了vue3.0,尤雨溪就把它改成用Proxy代理的方式来实现数据响应式。
Proxy的定义:代理的意思。就是你想要对数据进行操作,必须经过代理,让代理去帮你操作数据,你只需要对代理发号施令就可以了。相当于Proxy就是你的管家,你想买什么吃的,就跟管家说,管家会帮你去买。
使用Proxy:
const target = {
name: 'wjg',
age: 18
}
const proxy = new Proxy(target, {
get(target,prop) {
console.log('Get Value: ' + target[prop])
return target[prop]
// return target[prop] 等价于: return Reflect.get(target,prop)
},
set(target, prop, value) {
console.log('Set prop: ' + prop + ' to value:' + value)
target[prop] = value
// target[prop] = value 等价于: Reflect.set(target, prop, value)
}
})
console.log(proxy.name)
proxy.age = 19
console.log(proxy.age)
console.log(target.age)
解释:
Reflect.set(target, prop, value)
这个函数调用,它内部会帮我们try catch,操作失败它会返回一个fasle,就不至于导致程序异常。与Object.defineProperty的区别:
重写Proxy:
function deepClone(target) {
if(typeof target !== 'object' || target === null) {
return target
}
const res = target instanceof Array ? [] : {}
for(let key in target) {
if(target.hasOwnProperty(key)) {
if(typeof target[key] === 'object' && target[key] !== null ) {
res[key] = deepClone(target[key])
} else {
res[key] = target[key]
}
}
}
return res
}
function MyProxy(target, handler) {
const _target = deepClone(target)
Object.keys(_target).forEach(item => {
Object.defineProperty(_target, item, {
get() {
return handler.get && handler.get(target, item)
},
set(newVal) {
handler.set && handler.set(target, item, newVal)
}
})
})
return _target
}
const target = {
name: 'wjg',
age: 18
}
const proxy = new MyProxy(target, {
get(target, prop) {
console.log('Get Value: ' + target[prop])
return target[prop]
},
set(target, prop, value) {
console.log('Set prop: ' + prop + ' to value:' + value)
target[prop] = value
}
})
console.log(proxy.name)
proxy.age = 19
console.log(proxy.age)
console.log(target.age)
实现原理: