Vue 3.0 系列之 Runtime Core,对应代码版本 vue-next
这一节的内容太多了,看了两天,也才刚刚把源码读完,还有很多细节的地方没有看。先记录一下从创建一个 App 开始,Vue 做了那些事情吧。这一部分主要包括 各个 hook 的处理,异步依赖的处理以及更新虚拟 Dom 的处理。
js
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
一图胜千言
本来想写一些过程的,但是光画脑图,都花了半天时间。还是直接贴脑图结果吧。剩下的发下一篇文章
目录结构
对应文件的一些说明
- components: 原生组件
- BaseTransition.ts: HOC,Transition 组件,处理 transition 相关 hook
- KeepAlive.ts: HOC,Keep Alive 组件,添加 actived、deactived hook,缓存组件
- Portal.ts: 特殊组件,在 patch 的时候调用 Portal.process 函数
- Suspense.ts: 特殊组件,主要用于处理 setup 为异步函数的情况。在 patch 的时候做特殊处理
- helpers: renderer 相关辅助函数
- createSlots.ts: 创建 Slot
- renderList.ts: 创建 列表 负责函数
- renderSlot.ts: 创建 Slot VNode
- resolveAssets.ts: 查找当前实例上注册的的 component 或者 directive
- scopeId.ts: SFC 样式作用域 id 管理
- toHandlers.ts: v-on Object 格式的 key 转换成 on* 格式
- useCssModule.ts: 获取当前实例的 css
- useSsrContext.ts: 注入 SSRContext
- apiComputed.ts: 代码很少,两行代码,主要用于 track 依赖项
- apiCreateApp.ts: 创建 App 实例,实例相关配置和 mount 操作都在此处
- apiDefineComponent.ts: 嗯...,实现的函数,就一行,统一 component 的定义。其它代码都是为了服务 TypeScript 的 类型处理
- apiInject.ts: 保存自定义变量在当前实例上,并继承父实例的自定义变量,并在需要的时候注入到目标实例(provide/inject)
- apiLifecycle.ts: 向向前实例注入生命周期钩子,SSR 的时候不处理
- apiOptions.ts: 处理 2.x 的组件书写格式,把各个参数以 3.x 的方式处理,生命周期转换成 hook
- apiWatch.ts: 创建 watch,主要执行 source 的 getter,然后在 effect 里面开启 track,这样,就可以采集到所有的依赖项,然后当依赖项更改时,触发 callback
- component.ts: 主要处理 Vue 组件的 setup 函数
- componentProps.ts: 处理传给组件 props ,统一成 NormalizedProp。特殊处理了 boolean 类型的 prop,和 directive 的生命周期 hook
- componentProxy.ts: 定义 componentInternal 的 Proxy
- componentRenderUtils.ts: 创建组件的根节点渲染结果。对比两个 vNode,判断是否需要更新。更新高阶组件的 el 对象
- componentSlots.ts: 对 vNode 的 slots 做统一化处理,统一成 Slot
- directives.ts: 向 vNode 注入 directive 相关处理,以及执行 directive 相关的生命周期 hook
- errorHandling.ts: Vue 错误处理
- h.ts: jsx 的 createElement 函数
- hmr.ts: 调试开发时,动态更新相关内容,build 版本无关
- hydration.ts: 混合应用的相关 Dom 的创建
- index.ts: 入口,负责导出公共 api
- renderer.ts: 主要负责 diff vDom 以及执行 diff 之后的 patch
- scheduler.ts: 任务调度,主要用于在一个 tick 中执行所有数据的更新
- vnode.ts: 创建一个空的 Virtual Node
- warning.ts: 运行时警告提示,报错 vue 自己的 trace
完