目录

这里是源码解读的开头,开通这个笔记的原因是因为想要深入理解一下Vue3的原理,能够清晰地知道现代的前端框架的具体实现,一个优秀的框架是如何开发出来的。

看什么?

track和trigger

核心代码的阅读需要一定的时间,推荐从依赖存储结构+track/trigger入口 packages/reactivity/src/dep.ts 从这里开始,订阅者的实现,在也在dep.ts中的Dep、Link。普通对象的get/set如何调用track/trigger,packages/reactivity/src/baseHandlers.ts。访问类型、触发类型的枚举 packages/reactivity/src/constants.ts。

阅读顺序建议:先 dep.ts 里 targetMap + track/trigger,再对照 baseHandlers.ts 里谁在什么时机调用它们。

Map/Set的嵌套

文件内容
packages/reactivity/src/collectionHandlers.ts对 Map/Set/WeakMap/WeakSet 的代理:get/set/add/delete/clear、keys/values/entries/迭代器里如何 track/trigger,以及 ITERATE_KEY、MAP_KEY_ITERATE_KEY。
packages/reactivity/src/reactive.tstargetTypeMap 把 Object/Array 与 Map/Set 等分成 COMMON / COLLECTION,决定用 baseHandlers 还是 collectionHandlers。
packages/reactivity/__tests__/collections/Map.spec.ts、Set.spec.ts行为与边界用例,适合对照读源码。

Effect的作用域

文件内容
packages/reactivity/src/effectScope.tsEffectScope、activeEffectScope、父子 scope、pause/resume、与 stop 时收集子 effect。
packages/reactivity/src/effect.ts 里 ReactiveEffect 构造函数activeEffectScope 存在且 active 时把 effect 注册进 effects 数组。
packages/reactivity/__tests__/effectScope.spec.ts用

调度器

响应式层(单个 effect 何时跑)

文件内容
packages/reactivity/src/effect.tsReactiveEffect 的 scheduler 选项;无 scheduler 时走 runIfDirty()。notify() → batch() → endBatch() 里统一 trigger()。startBatch/endBatch 与 dep.ts 里 trigger 包在一起,避免同步多次更新抖动。

运行时层(组件更新队列、nextTick)

文件内容
packages/runtime-core/src/scheduler.tsqueueJob、flushJobs、nextTick、组件 render effect 如何被排队(和「纯 reactivity」的 batch 是不同一层)。
packages/runtime-core/src/renderer.ts(搜 effect.scheduler)组件级 effect 如何把 scheduler 设为 queueJob(job)。

深度响应式转换

文件内容
packages/reactivity/src/reactive.tsreactive/readonly/shallowReactive 等、createReactiveObject、reactiveMap 等 WeakMap 缓存、与 handler 的选用。
packages/reactivity/src/ref.tsref、嵌套 ref 解包与 triggerRef。
packages/reactivity/src/baseHandlers.ts深层代理时 get 里对子对象的 reactive/readonly 包装。
packages/reactivity/src/arrayInstrumentations.ts数组方法(includes、push 等)的特殊 instrument,避免重复 track 或语义问题。

边缘情况与测试

优先看 packages/reactivity/__tests__/ 下与主题对应的 spec(例如 effect.spec.ts、reactive.spec.ts、reactiveArray.spec.ts、effectScope.spec.ts、collections 目录)。这些文件往往直接对应「容易踩坑」的行为。

注意

区分编译时和运行时

我们需要有一个虚拟DOM,调用渲染方法将虚拟DOM渲染为真实的DOM,缺点就是虚拟DOM编写比较麻烦,专门写一个编译时可以将模板编译成虚拟DOM(构建的时候进行编译性能更高,不需要在运行的时候进行编译,并且Vue3在编译中也做了很多的优化)。

Vue3 的模块拆分

Vue3的模块之间耦合度都比较低,模块可以独立使用,拆分模块很方便。通过摇树机制按需引入,可以减少用户打包之后的体积,组合式API。Vue3还可以自定义渲染器,扩展能力很强,扩展比较方便。

文件夹

![[Pasted image 20260407133505.png]]