Vue2与Vue3的双向数据绑定(二)

Vue2采用了defineProperty

Vue2.x实现双向数据绑定原理,是通过ES5的 Object.defineProperty,根据具体的key去读取和修改。其中的setter方法来实现数据劫持的,getter实现数据的修改。但是必须先知道想要拦截和修改的key是什么,所以vue2对于新增的属性无能为力,比如无法监听属性的添加和删除、数组索引和长度的变更,vue2的解决方法是使用Vue.set(object, propertyName, value) 等方法向嵌套对象添加响应式。

  class Vue {
        constructor(options) {
            const { data } = options
            const _data = data()
            for (let key in _data) {
                Object.defineProperty(this, key, {
                    get() {
                        return _data[key];
                    },
                    set(newval) {
                        _data[key] = newvalF
                    }
                })
            }
        }
    }
    const vm = new Vue(
        {
            data() {
                return {
                    a: [1, 2],
                    b: ["a", "b"]
                }
            }
        }
    );
    vm.a = [3, 4]     
    vm.a.push(5)
    console.log(vm.a); //[3, 4, 5]
复制代码

Vue3采用了Proxy

Proxy可以理解成,在对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy可以直接监听对象而非属性,并返回一个新对象,具有更好的响应式支持

class Vue {
        constructor(options) {
            const { data } = options
            const _data = data()
            return new Proxy(_data, {
                get(obj,name) {
                        return obj[name];
                    },
                    set(obj,name,newval) {
                       obj[name] = newval
                    }
            })
        }
    }
    const vm = new Vue(
        {
            data() {
                return {
                    a: [1, 2],
                    b: ["a", "b"]
                }
            }
        }
    );
    vm.a = [3, 4]
    vm.a.push(5)
    console.log(vm.a);//[3, 4, 5]
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享