vue3阅读记录(四)

141 阅读2分钟

「这是我参与2022首次更文挑战的第33天,活动详情查看:2022首次更文挑战

image.png

这一次,我们关注的是更新机制

setupRenderEffect

虽然我从createApp进去,但是主要看setup里面的setupRenderEffect, 更新的回调就是定义在这里面的。 这个函数的主逻辑就是定义了一个componentUpdate,挂到监听和 组件实例的update上。

定义完毕之后,开始执行 run,run的主要逻辑就是执行更新函数。这里就是注册更新函数的时候,也就是收集依赖的时候。

image.png

flowchart LR
      1[createApp]--> 2[setup] --> 3[setupRenderEffect] --> 4[定义componentUpdate] --> 5[run] 

触发更新后

这个setInerval,是我写的用来触发更新机制的, 可以看到,先是set。set就表示我修改的这个动作被捕获了, 然后就触发了一系列动作,这个匿名函数就是上面 new RectiveEffect 的第二个参数 返回queueJob(effect)的调用。 queueJob来判断是否是要给当前job加入队列。 queueFlush是给一个已经解决的期约注册then的回调,这个回调就是 flushJobs.如果没注册过的话。


flowchart LR

set被捕获 -->  triggerRefValue --> triggerEffects --> 匿名函数 -->queuejob --> queueFlush

执行到这就没有了,已经是栈顶了,然后是一个异步的 ,新开的栈.这里的effect就是在前面用ReactiveEffect创建的。

时机到了开始更新

flowchart LR
flushJobs--> 有错误处理的调用--> effect.run --> 更新的回调componentUpdate

异步,说明前面的捕获了我们修改的动作之后,不会立即更新,而是统一等当前宏任务栈空之后,再批量处理。 flushJobs里面主要的逻辑就是遍历queue(这个队列里装的就是我们的依赖instace.effect),执行 callWithErrorHandling(job, null, ErrorCodes.SCHEDULER), 这个函数的主要作用就是执行job,并捕获可能的错误。

image.png

我这里用的是ref的响应式,一会儿再改成reactive的。ref的依赖收集和触发和之前基本上还是一样,get的时候收集traceRefValue , set的时候触发triggerRefValue。 并且这里还要自己包装一下,所以直接就用了字面量对象来设置访问器属性setter和getter。 一目了然

这里别人写了一堆注释。 前三行的意思就是说这个include查找使用了第二个参数发fromIndex,从什么位置开始. 默认情况下,会包括正在执行的job,这样就不会递归执行job了。

后三行却说,如果这个job是一个watch的回调,那么就从a+ 1开始。 这样就可以这个job就可以递归调用自己,如果出现了死循环那就是用户的责任了。 这是免责声明吗,哈哈。

image.png