Vue2和Vue3的响应式原理

vue2响应式原理

对象类型: 通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)
数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)

                // Object.defineProperty(obj, prop, descriptor)
                // obj   要定义属性的对象。
                // prop 要定义或修改的属性的名称或 Symbol 。
                // descriptor   要定义或修改的属性描述符。
                // 返回值  被传递给函数的对象。

                let person = {
                    name: '张三',
                    age: 15,
                }
                let p = {}
                Object.defineProperty(p, 'name', {
                    configurable: true, //配置这个属性表示可删除的,否则delete p.name 是删除不了的 false
                    get() {
                        //有人读取name属性时调用
                        console.log('读取');
                        return person.name
                    },
                    // 属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。 
                    set(value) {
                        //有人修改时调用
                        console.log('有人修改');
                        person.name = value
                    }
                })
                console.log(p.name);
                p.name = "李四"
                console.log(p.name);

控制台结果
在这里插入图片描述

Vue3响应式原理

            let person = {
                    name: '张三',
                    age: 15,
                }
                //我们管p叫做代理数据,管person叫源数据
                const p = new Proxy(person, {
                    //target代表的是person这个源对象,propName代表读取或者写入的属性名
                    get(target, propName) {
                        console.log('有人读取了p上面的propName属性')
                        return target[propName]
                    },
                    //不仅仅是修改调用,增加的时候也会调用
                    set(target, propName, value) {
                        console.log(`有人修改了p身上的${propName}属性,我要去更新界面了`)
                        target[propName] = value
                    },
                    deleteProperty(target, propName) {
                        console.log(`有人删除了p身上的${propName}属性,我要去更新界面了`)
                        return delete target[propName]
                    },
                    isExtensible(target, propName) {
                        console.log(propName);
                        return target[propName]
                    }
                })
                //映射到person上了,捕捉到修改,那就是响应式啊
                console.log(p.name);// 读取 
                p.name = "李四"    //  修改
                console.log(p.name);
                delete p.name  //  删除
                p.sex = "男" // 新增 也调set

控制台结果:
在这里插入图片描述
vue3底层源码不是我们上面写的那么low,实现原理一样,但是用了一个新的方式
通过Proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等等。
通过Reflect(反射):对被代理对象的属性进行操作
MDN文档中描述的Proxy与Reflect:可以参考对应的文档
最终Vue3的响应式原理:

                let person = {
                    name: '张三',
                    age: 15,
                }
                //我们管p叫做代理数据,管person叫源数据
                const p = new Proxy(person, {
                    //target代表的是person这个源对象,propName代表读取或者写入的属性名
                    get(target, propName) {
                        console.log('有人读取了p上面的propName属性')
                        //  Reflect.get()  类似于 target[propName] 读取属性值 只是通过函数执行
                        return Reflect.get(target, propName)
                    },
                    //不仅仅是修改调用,增加的时候也会调用
                    set(target, propName, value) {
                        console.log(`有人修改了p身上的${propName}属性,我要去更新界面了`)
                        Reflect.set(target, propName, value)
                    },
                    deleteProperty(target, propName) {
                        console.log(`有人删除了p身上的${propName}属性,我要去更新界面了`)
                        console.log(Reflect.deleteProperty(target, propName));
                        return Reflect.deleteProperty(target, propName)
                    }
                })
                console.log(p.name);
                p.name = "李四"
                delete p.name

控制台如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值