vue Object.defineProperty Proxy 数据双向绑定
作者:互联网
Object.defineProperty
虽然已经能够实现双向绑定了,但是他还是有缺陷的。
- 只能对属性进行数据劫持,所以需要深度遍历整个对象
- 对于数组不能监听到数据的变化
虽然 Vue 中确实能检测到数组数据的变化,但是其实是使用了 hack 的办法,并且也是有缺陷的。
const arrayProto = Array.prototype export const arrayMethods = Object.create(arrayProto) // hack 以下几个函数 const methodsToPatch = [ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ] methodsToPatch.forEach(function(method) { // 获得原生函数 const original = arrayProto[method] def(arrayMethods, method, function mutator(...args) { // 调用原生函数 const result = original.apply(this, args) const ob = this.__ob__ let inserted switch (method) { case 'push': case 'unshift': inserted = args break case 'splice': inserted = args.slice(2) break } if (inserted) ob.observeArray(inserted) // 触发更新 ob.dep.notify() return result }) })
反观 Proxy 就没以上的问题,原生支持监听数组变化,并且可以直接对整个对象进行拦截,所以 Vue 也将在下个大版本中使用 Proxy 替换 Object.defineProperty
let onWatch = (obj, setBind, getLogger) => { let handler = { get(target, property, receiver) { getLogger(target, property) return Reflect.get(target, property, receiver) }, set(target, property, value, receiver) { setBind(value) return Reflect.set(target, property, value) } } return new Proxy(obj, handler) } let obj = { a: 1 } let value let p = onWatch( obj, v => { value = v }, (target, property) => { console.log(`Get '${property}' = ${target[property]}`) } ) p.a = 2 // bind `value` to `2` p.a // -> Get 'a' = 2
标签:vue,const,target,Object,value,let,Proxy,property,inserted 来源: https://www.cnblogs.com/mengfangui/p/10506063.html