如何在不看源码情况下学 petite-vue 源码
大家好,我是卡颂。
周末没啥事,准备找个优秀且代码量不多的库学习下。最终选择了最近发布的petite-vue,原因如下:
代码量少(只有5.8kb),且源码模块化程度高(相比于
React),易读基于
Vite构建,执行yarn dev就能开始调试源码没有
虚拟DOM、编译时方案,可以作为读Vue源码的铺垫底层的响应式更新原理同样适用于
Mobx、SolidJS等库,一次阅读多份收获

Vue了,如何才能高效学习源码呢?petite-vue为例为大家示范学源码的正确姿势。怎么快怎么来
petite-vue理解为:用真实DOM取代Vue模版的简易Vue。Demo:<script type="module">
import { createApp } from '../src'
createApp({count: 0}).mount()
</script>
<div v-scope>
<button @click="count++">add 1</button>
<p>{{count}}</p>
</div>
div及其子孙节点是真实的DOM标签,所以页面初始化时如下:
petite-vue初始化:createApp({count: 0}).mount()


Performance面板看看首屏渲染的调用栈:

createContext与reactive关键词判断大概是创建响应式上下文。至于响应式的含义,我们还不清楚。
遍历
DOM完成数据与视图的双向绑定
初始化渲染
验证遍历DOM
walk与walkChildren被调用多次,大概率他们就是具体遍历工作执行的方法,让我们确认下。walk方法中打上log:export const walk = (node: Node, ctx: Context): ChildNode | null | void => {
console.log('walk', node);
// ...
}
"\n "对应的文本节点,打印顺序如下:walk div
walk <button>add 1</button>
walk "add 1"
walk <p>0</p>
walk "0"
petite-vue mount时采用深度优先遍历,并对遍历到的每个与上下文状态相关的DOM节点进行处理。Demo中,上下文包含状态{count: 0}:createApp({count: 0}).mount()
<p>{{count}}</p>变为<p>0</p>。确定双向绑定的粒度
DOM会被重新遍历并执行相应DOM操作?Performance后,点击<button>add 1</button>触发更新:
walk、walkChildren(或类似遍历过程),只调用了reactiveEffect一个方法就更新了DOM。mount时的深度优先遍历建立了状态与更新DOM的方法之间一一对应的关系。DOM。状态后,只需要找到与他有关系的更新DOM的方法执行就行。count状态与如下函数建立联系:function setCount(value) {
p.textContent = value;
}
count变化后调用setCount(count)就能更新p对应DOM。petite-vue的工作原理,主要包括两点:mount时深度优先遍历DOM,对有状态的DOM(比如<p>{{count}}</p>)建立状态与更新DOM的方法之间一一对应的关系update时找到该状态对应的更新DOM的方法并执行
Vue Mastery的Vue 3 Reactivity课程,可以补齐响应式更新这块知识。
总结
从
mount时与update时的调用栈推导出整体工作流程从
整体工作流程中发现核心知识 —— 响应式更新
整体工作流程与响应式更新后,再阅读自己感兴趣的部分才不至于陷入庞大的代码量中。

评论
