欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

双向数据绑定(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补充版本如下:

相关标签: 前端