vue 低层次原理(第一章)

vue的响应式原理

响应式

vue2响应式原理就是通过object.defineProperty来劫持对象上的get和set方法,通过对象上的复杂数据类型递归的方式实现复杂数据劫持,然后通过发布订阅者模式来通知前端视图层更新,从而实现响应式(他还只会监听原有的数据和对象)。
vue3的响应式相对于vue2是比较简单的,它是直接通过proxy代理来监听对象的get和set值,然后返回一个proxy对象,然后通过发布订阅者模式更新前端视图

自我总结

vue2相对于vue3来说实现的响应式更加消耗性能,vue3在底层中其实也使用到了递归,但是相对于vue2一开始就是便利对象然后进行判断处理是否为复杂数据类型,如是则会递归监听复杂数据类型。
而vue3是在获取数的时候进行判断获取值是否为复杂数据类型,如是则递归深度代理。

vue2监听(简洁版)

 let obj = {
            username  : "小编泰裤了"
        }
        function monitor(target,key,value){ //定义函数进行监听
            Object.defineProperty(target,key,{
                get(){
                    return value
                },
                set(newVal){
                    if(newVal != value){
                        value = newVal
                        observer(newVal)
                    }
                }
            })
        }
        function observer(data){
            if(typeof data !='object' || typeof data == null){//做判断来看你是否为复杂数据类型,是则递归便利
                observer(data)
            }
            for (const key in data) {
                monitor(data,key,data[key])
            }
        }
        observer(obj)
        console.log(obj);

vue3监听(简洁版)

<script>
        let obj = {
            username: "小编泰裤了"
        }
        let headle = {
            get(target, key) {
                let temp = target[key]
                if(typeof temp == 'object'){
                    return monitor(temp)
                }
                return temp
            },
            set(target, key, value) {
                target[key] = value
            }
        }
        function monitor(data) {
            return new Proxy(data, headle)
        }
        let user = monitor(obj)
        console.log(user);
    </script>

vue2数组监听

数组考虑到defineProperty的消耗,所以没有做监听,但是vue2对数组的【push,unshift,shift,prop,splice,sort,resver】(重写数组的方法)进行了重写的方式来对数组劫持
,同时也通知前端视图更新

缺点

不能监听数据的索引和长度的变化

底层代码实现

<script>
        let obj = {
            num: 12,
            username: '小编太酷了',
            gradeList: [1, 2, 3, 4, 5]
        }
        let newArrayProprotype = Object.create(Array.prototype);
        let oldArrayProprotype = Array.prototype;
        ['push', 'sort', 'resver', 'unshift', 'shift', 'splice', 'pop'].forEach((mthd) => {
            newArrayProprotype[mthd] = function (...ary) {
                console.log("用户调用了数组方法中的:", mthd);
                return oldArrayProprotype[mthd].call(this, ...ary)
            }
        })

        function constest(target, key, value) {
            observer(value)
            Object.defineProperty(target, key, {
                get() {
                    return value
                },
                set(newVal) {
                    if (value != newVal) {
                        value = newVal;
                        observer(newVal)
                    }
                }
            })
        }
        function observer(data) {
            if (typeof data != "object" || typeof data == null) {
                return
            }
            if (Array.isArray(data)) {
                data.__proto__ = newArrayProprotype
            } else {
                for (const key in data) {
                    constest(data, key, data[key])
                }
            }
        }
        observer(obj)
        obj.gradeList.push(6, 7, 8)
        console.log(obj.gradeList);
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值