推广

vue源码解读–计算属性

iseeyu2年前 (2024-02-21)推广121

默认情况下页面将渲染出”default”,当我们第一次点击onChangeIndex函数后将显示”三岁就会写bug”,同时打印出”update”,当再次点击则页面不会有变化,但是仍然打印出”update”;当点击onChangeName后页面展示”三岁就会写bug哦”,同时打印”update”,当再次点击时,则页面无变化同时不会打印”update”.

那么为什么会这样呢?

几个小

我们之前在分析组件的createComponent和组件的init时候都跳过了部分关于computed的逻辑

     在组件创建的过程中,调用extend,判断computed是否存在,然后进行计算属性的init,继而调用defineComputed

     在组件的init过程中,调用initState方法,该方法除了对props、data执行了相关逻辑外,还判断了computed是否存在,并在存在时调用其init,继而调用defineComputed

        也就是说,vue在构建组件构造器时候便已经对compoted进行了处理,而处理函数即defineComputed,那么我现在有3个疑问:a-为什么要提前处理?b-两处处理有什么不同?c-只处理一次行不行?

         首先看extend中的处理

                     首先拿到组件的options对象,并对computed进行遍历,并对每一个key(name函数)调用defineComputed,入参为组件的原型、name函数

             再看init过程

            可以看到,两次都是拿到computed的key遍历调用defineComputed,不一样的是,一次传入的target是实例的原型,一次则是vm实例。我们都知道this会首先查找实例本身,若不存在则跟随原型链查找原型对象。且for…in循环具有查找原型链的能力。也就是说,同一个组件,只会在构建构造器时候执行一次。当对组件进行初始化时候,for…in将查找到原型上存在的key,故不会重复多次调用defineComputed。这可以认为是一种”数据共享”,是一种优化手段

            所以,之前的疑问可以这么回答:为了避免当在同一个页面中多次使用同一个组件时每次都在组件中定义一遍key造成性能浪费,便利用原型链特性一劳永逸的在构建组件阶段放置到原型链上以避免走重复逻辑(疑问a、b);只在组件上定义会存在a、b提出的性能问题,而只在原型上定义则无法针对如mixin一类后植入的key进行处理(疑问c)

创建过程

当执行组件初始化过程中会调用initState并判断computed存在执行initComputed,传入组件实例和在组件中定义的computed对象(我们这里即name函数)

        –向组件实例挂载_computedWatchers,默认是空对象,并通过Object.create赋予其原型链访问权力

        –isSSR在浏览器环境下为false,进入判断,进行watcher实例化。入参为:组件实例、getter函数(name函数)、noop空函数、{ lazy: true }。实例化watcher的关键信息如下

(在计算时作为判断条件)

(在计算时调用)

(可以看到,在创建过程中并没有调用get进行计算,而是返回undefined)

        –使用for…in循环拿到每一个key,即我们定义的每一个函数

        –向实例的_computedWatchers上绑定一个watcher,从之前文章的分析我们知道watcher将在一定的时机触发update进行patch最终渲染为dom

        –调用defineComputed,将组件实例、每一个计算属性的key及其对应的处理函数(name函数)传入

                –shouldCache为true    

                –sharedPropertyDefinition.get对应的是一个匿名函数

                –由于将sharedPropertyDefinition作为Object.defineProperty的属性描述符,故当访问this.name时,将会触发拦截从而调用sharedPropertyDefinition的get方法,而get方法指向上一步返回的computedGetter函数

计算过程–default

        当vue将组件编译为render函数的过程中将对模板中的变量name进行访问,此时将触发sharedPropertyDefinition的get,即computedGetter函数

        –拿到我们在创建过程中保存的每一个computed.key对应的watcher

        –调用evalute函数

                 调用get函数,求值

                    –向dep.target保存this

                    –调用getter函数,即name函数

(计算得出’default’并返回)

        –调用depend函数

                这实际上调用的是

(经过之前的分析,我们知道这实际上是一次依赖收集。其中dep是发布者,watcher是订阅者,这里为了在发布者中保存订阅以便在适当的时机去发布广播触发更新)

因此,得出的值为”default”

计算过程–三岁就会写bug

        当我们点击onChangeIndex函数将手动把saveIndex加加,由于saveIndex是在data中定义的响应式数据,故它将首先走向get方法进行依赖收集,此时dep中将有两个订阅者:计算属性name和saveIndex

        加加的操作则触发saveIndex的set方法,将触发dep的notify

            继而调用watcher的update,由于第一个dep是计算属性的,故只会执行到this.lazy中将this.dirty置为true后便会调用saveIndex对应watcher的update,此次将触发queueWatcher执行render,而在render的过程中将再次访问name,此时this.saveIndex>0成立,获取firstName和lastName并计算返回

因此,得出的值为”三岁就会写bug”

最后关于”当点击onChangeName后页面展示”三岁就会写bug哦”,同时打印”update”,当再次点击时,则页面无变化同时不会打印”update”.”,主要是因为在set拦截中进行了值比较,当相等时则return,因此不会重新render,故而无法调用update

可以看到,当其依赖项发生变化时总是会重新求值,但是如果求出的值相等时vue并没有做限制,而是每次都重新计算了一次。这样的不合理可能是由于我当前看的源码版本(2.5.2)较老导致的,毕竟尤大这样的神级人物不会考虑不到这一点

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://www.0291.com.cn/post/57218.html

相关文章

早安语录正能量图片励志文字,你要努力变优秀,然后骄傲的生活

早安语录正能量图片励志文字,你要努力变优秀,然后骄傲的生活

心如大海,潮起潮落,成功的起点是在山穷水尽时,希望的萌生是在峰回路转时,只要心中有一轮太阳,又何惧世事沧桑,若能一切随它去,便是人间好时节。早安,周四!如果一个气球想要飞翔,就要吞下一肚子的气去长大,如果要征服一座高山,就要习惯不习惯的缺氧!早安,周四!天空不总是晴朗,阳光...

于斐老师谈:中小企业数字化时代营销策略与方法(六)

于斐老师谈:中小企业数字化时代营销策略与方法(六)

蓝哥智洋国际行销顾问机构 于斐如今,他们正在遭受清算……按照这种速度,能够生存下来的企业将寥寥无几。企业倒闭已经不仅仅是或者亏钱的问题,而且意味着自己失去了存在的价值,估计很多老板则连原始积累都要搭进去,怎么吃下去的就会怎么吐出来。为此,企业转型需要进行两种性质的调整:第一...

小编分享SEO优化是否过时了。

小编分享SEO优化是否过时了。

现在很多的企业得不到期望的利益,其实并不是缺乏好产品,只是缺乏好的营销罢了。而对于当下网络营销来说,seo优化是其中的关键,所以做好优化是很多企业都需要重视的问题。要符合SEO要求,注意不要SEO作弊,这样才能让企业更好的开展营销。 一、SEO是否没用了? 产品需...

市场营销常用十二种手段

市场营销常用十二种手段

  经济体制下竞争无处不在,企业要想在竞争环境下得以存活赢取自身的市场地位,有效防范竞争提高自身的竞争优势是必须要做的。商业竞争手段有哪些?有哪些手段又能帮助企业突出重围,正睿总结出营销管理咨询中常用到的商业竞争的九种手段以及十二种营销攻击手段。  商业竞争常用九种手段  ...

财富管理人才未来之路——需求旺盛,但高素质人才不足!前 ...

财富管理人才未来之路——需求旺盛,但高素质人才不足!前 ...

(本文发表在公号“R姐的商业圈”,订阅公号“R姐的商业圈”,一起了解更多商业与财富的攻略)临近年底,总有一个词在我的耳边反复萦绕——“不确定性”。近期很多资深大咖以及各大媒体平台都在积极筹备、发布了年终秀。笔者躺平的这些天看了许多个“h”的商业演讲和观点评论。大家都在深度放...

如何解决文章排名不在首页的问题。

如何解决文章排名不在首页的问题。

当网站发布文章被搜索引擎收录并且有排名之后,怎么让它往前靠?这是今天一个小伙伴问我的问题,相信出现这种情况的朋友不在少数,在这里我就给大家说说我的方法。 我们可观察下那些排名比较好的网站,你可以去观察他们的页面布局,关键词密度,都有做到做到集权,换句话说自己的内容页分权了。所以导致文章排名不行,栏...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片