双向数据绑定(Proxy 和 Object.defineProperty )
程序员文章站
2022-07-12 22:49:19
...
Proxy 和 Object.defineProperty
的区别
这两个属性本身就不是在同一个领域工作的,我们通常说的区别,也仅仅是针对使用了这两个 API 的 Vue 的双向绑定机制的实现。
因此,在回答的时候,通常可以直接说出 Vue 来使用这两种机制来实现双向绑定的优劣势。
Object.defineProperty
版本
const obj = {}
Object.defineProperty(obj, 'prop', {
get() {
console.log('get val')
},
set(newVal) {
console.log(newVal)
document.getElementById('input').value = newVal
}
})
const input = document.getElementById(input)
input.addEventListener('keyup', function(e) {
obj.text = e.target.value
})
可以看出这个简单版本透露出来一个很明显的缺点,那就是只能对对象的属性进行监听,如果需要监听多个属性,则需要进行遍历。同时,这个 API 无法监听数组。
当然他的优点就是兼容性好。
Proxy 版
const input = document.getElementById(input)
const obj = {}
const newobj = new Proxy(obj, {
get(target, key, receiver) {
console.log(`getting ${key}`)
return Reflect.get(target, key, receiver)
},
set(target, key, value, receiver) {
console.log(target, key, value, receiver)
if(key === 'text') {
input.value = value
}
return Reflect.set(target, key, value, receiver)
}
})
input.addEventListener('keyup', function(e) {
obj.text = e.target.value
})
从上述可以看到,Proxy 可以对整个对象进行代理拦截,并且返回一个新的对象。除此之外还可以对数组进行拦截。
Proxy 最大的问题便是兼容性不好,并且无法通过 polyfill 磨平。
proxy补充版本如下: