最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 记一次比较Vue2和Vue3响应式原理和性能差异

    正文概述 掘金(Vite)   2021-02-28   569

    写在前面

    Vue响应式原理是数据驱动视图的核心,它能够自动帮助开发者监听数据的变化,最终触发视图更新。它是Vue的渲染更新过程的核心。那么了解这一部分的原理至关重要,这篇文章就结合vue2vue3响应式来做一个对比,既明白了响应式原理的实现,又对比了二者在性能上的差异~

    需要了解的api

    这篇文章不是零基础,需要对一些基础api有一定的了解,那么这里给出这些api的官方文档,供大家参考学习:

    • vue2响应式原理

    Object.defineProperty

    • vue3响应式原理

    Proxy

    Reflect

    准备一个原始对象数据

    为了做这个实验,我使用同一个数据对象来分别做vue2vue3的示例:注意这个data数据从最外层花括弧到最里层总共8个层级,你可以数一下。

    const data = {
        username: 'tom',
        profile: {
            city: 'beijing',
            a: {
                b: 12,
                c: {
                    d: 23
                }
            }
        }
    }
    

    接下来我分别写点代码对这个数据做响应式处理:

    • vue2
    const data = {
        username: 'tom',
        profile: {
            city: 'beijing',
            a: {
                b: 12,
                c: {
                    d: 23
                }
            }
        }
    }
    function observe(data) {
        console.log(1);
        if (typeof data !== 'object' || data == null) {
            return data
        }
        for (const key in data) {
            defineReactive(data, key, data[key])
        }
    }
    
    function defineReactive(target, key, val) {
        observe(val)
        Object.defineProperty(target, key, {
            get() {
                console.log(`get ${key}`);
                return val
            },
            set(newValue) {
                console.log(`set ${key}`);
                if (newValue !== val) {
                    observe(newValue)
                    val = newValue
                }
            }
        })
    }
    observe(data);
    console.log(data);
    

    打印的结果如下: 记一次比较Vue2和Vue3响应式原理和性能差异 从图中可以清晰的看到总共打印了8次1,也就是说observe一共执行了8次;由此可见vue2是一次递归到底的来实现响应式的,好接下来看看vue3:

    • vue3
    function observe(data) {
        console.log(1);
        if (typeof data !== 'object' || data == null) {
            return data
        }
        const p = new Proxy(data, {
            get(target, key, receiver) {
                console.log(`get ${key}`)
                const result = Reflect.get(data, key, receiver)
                // 当获取值的是时候 再设置响应式
                return observe(result)
            },
            set(target, key, val, receiver) {
                console.log(`set ${key}`)
                const result = Reflect.set(target, key, val, receiver)
                return result
            }
        })
        return p
    }
    
    const data = {
        username: 'tom',
        profile: {
            city: 'beijing',
            a: {
                b: 12,
                c: {
                    d: 23
                }
            }
        }
    }
    
    const p1 = observe(data)
    console.log(p1)
    

    打印结果如图: 记一次比较Vue2和Vue3响应式原理和性能差异 只打印了一次1,也就是说observe只执行了一次,从代码可以看出,将来执行get的时候,observe又会再次执行。什么意思呢?也就是说Vue3对于数据的深层监听只有当获取值的时候才会响应式处理,这样在性能上肯定会提升很多。

    争议

    读到这里,抛开其他细节来讲,可能你会来句卧槽,那Vue2也可以在get的时候observe啊,确实如此,但是想一下是不是会有点问题呢?问题就在于每次执行get的时候,不管是获取哪个属性,都需要执行一下observe,并且它还是会向下遍历,这样增加了时间复杂度,可想而之,其性能是多么浪费的,还不如一次性深度监听到底呢?而proxy则不一样,它只会响应式处理你get的那个层级,它不会深度遍历,这样解释你明白了吗?

    总结

    接下来总结一下二者响应式的差异

    • Object.defineProperty
      • 深度监听,性能问题
      • 新增删除属性问题,这个可以参考我前面写的一个文章总结一下Vue那些常用必会面试必考的API,这里说明了vue2为什么需要set&delete两个api
      • 数组问题,需要重写数组原型的几个方法
    • Proxy
      • 性能提升了一大截
      • 解决了vue2的那些问题
      • 兼容性有待处理

    当然示例代码都没做优化,实际上源码肯定是对各种情况还做了处理,这里就不做介绍了,可以自己去看源码哈~如果你对本文有什么看法或者觉得不对的地方,请在评论区赐教!共勉进步~~

    参考

    vue2响应式原理

    vue3响应式原理


    起源地下载网 » 记一次比较Vue2和Vue3响应式原理和性能差异

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元