vue3源码之effect

44 阅读2分钟

前言

这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情   响应式是vue的发动机,在响应式里面另外一个核心api就是effect,在我们平时写业务的时候用不到effect,但是它在vue3响应式源码那块却起到至关重要的作用。

正文

effect中文翻译过来叫副作用,传入的参数为fn函数,先看下源码里面的一组单测,从单测的名字以及commit记录可以发现,effect起到的是观察者的作用。在源码里面,effect会在reactive执行执行之后先执行一次,当reactive里面的值发生改变的时候,会发现effect会继续执行。

image.png 接下来看源码实现,查看effect文件,会发现一个比较重要的类ReacttiveEffect。

可以看到一系列的参数,active代表是否在执行状态,deps对应依赖收集容器,computed代表一个可选参数,是计算属性的意思,翻阅computed源码会发现computed的实现也依赖ReacttiveEffect这个类。

image.png 继续往下翻ReacttiveEffect这个类,参数如下图所示,dev下面的参数暂时先不研究。其中onStop代表的是执行stop之后的后序操作,执行stop的时候,会清除deps里面的dep. image.png 查看run的源码,在执行effect的时候会执行run。前两行代表说明effect里面的fn会率先执行一次。其中shouldTrack的意思是是否需要收集依赖,当为false的时候,就不需要收集依赖,说明响应式的值没有发生改变。

image.png

查看stop源码,可以发现stop用的是cleanupEffect去清空deps的,其中cleanupEffect的实现相对比较简单,这里就不详细介绍了。

image.png 到这里,我们去翻看effect这个方法里面的实现,会发现基于ReactiveEffect这个类实现的。最后返回的runner就是ReactiveEffect的run方法。

image.png 继续往下翻会发现track和trigger方法,其实这块应该放在reactive那一块介绍。Track对应收集依赖,trigger对应触发依赖。在reactive里面我们提到createSetter和createGetter这两个方法,其中就是track在createGetter里面执行,trigger在createSetter里面执行。

翻阅track源码,如下图所示,其中set流程为target -> key -> dep。

image.png 继续翻阅trigger源码,然后发现大致流程为trigger->triggerEffects->triggerEffect,一步到位,我们来看triggerEffect里面的核心部分,发现还是effect里面的run方法实现的,在这里我们可以看到有scheduler的存在。scheduler是任务调度器,有它在,就不会先执行副作用函数,就会先执行scheduler。

image.png

最后

到这里effect源码就研究完了,日拱一卒,坚持不懈,学习源码是为了日后造工具,而不是为了学习而学习。