Vue2和Vue3响应式原理

226 阅读2分钟

vue2响应式原理

vue2使用Object.defineProperty()对数据进行劫持,只能捕获到读取属性和修改属性的操作,无法捕获到添加属性和删除属性的操作。

具体代码:

       // 源数据
        const _data = {
            a:"aaa",
            b:"bbb"
        }
        // 创建一个空对象
        const data = {
            
        }
        // 使用 Object.defineProperty()对数据进行劫持,
        // 传入三个参数,第一个是代理对象,第二个代理对象的属性,第三个是一个配置对象,包含get、set函数
        Object.defineProperty(data, "a", {
            // 当读取data中的a属性时,调用此函数
            get(){
                console.log("有人读取了data中的a属性");
                return _data.a;
            },
            // 当修改data中的a属性时,调用此函数,参数为修改的值
            set(val){
                console.log("有人修改了data中的a属性");
                _data.a = val;
            }
        })
        // 属性b同理
        Object.defineProperty(data, "b", {
            // 当读取data中的b属性时,调用此函数
            get(){
                console.log("有人读取了data中的b属性");
                return _data.b;
            },
            // 当修改data中的b属性时,调用此函数,参数为修改的值
            set(val){
                console.log("有人修改了data中的b属性");
                _data.b = val;
            }
        })

vue2响应式原理.png

vue3响应式原理

vue3与vue2不同,vue3使用proxyreflect对数据进行劫持和代理,既能捕获到读取属性和修改属性的操作,也可以捕获到添加属性和删除属性的操作。

具体代码:

        // 源数据
        const _data = {
            a: "aaa",
            b: "bbb"
        }
        // 使用 Proxy、Reflect对数据进行代理和劫持,
        // 传入两个参数,第一个是代理对象,第二个是一个配置对象,包含get、set、deleteProperty函数
        const data = new Proxy(_data, {
            // 当读取某个属性时,调用此函数,第一个参数为代理的目标对象,第二个参数为读取的属性
            get(target, property) {
                // 通过Reflect获取目标对象的属性
                console.log(`有人读取了data中的${property}属性`);
                // 通过Reflect获取目标对象的属性
                return Reflect.get(target, property);
            },
            // 当修改和添加某个属性时,调用此函数,第一个参数为代理的目标对象,第二个参数为要修改或添加的属性,第三个参数为修改或添加的值
            set(target, property, val) {
                console.log(`有人修改了data中的${property}属性`);
                // 通过Reflect修改或添加目标对象的属性
                Reflect.set(target, property, val);
            },
            // 当删除某个属性时,调用此函数,第一个参数为代理的目标对象,第二个参数为要删除的属性
            deleteProperty(target, property) {
                console.log(`有人删除了data中的${property}属性`);
                // 通过Reflect删除目标对象的属性
                return Reflect.deleteProperty(target, property);
            }
        })

vue3响应式原理.png