Vue 渲染管线的三大阶段
Vue 的渲染管线可以划分为三个核心阶段,对应三个核心模块的协作流程。
阶段一:编译(Compile)
编译器将 HTML 模板编译为 render function(渲染函数)。
为什么要编译成函数?主要原因是渲染函数需要与响应式对象配合,当数据变化时可以重新调用函数生成新的 vnode 树。编译器通常在 Vue 的构建阶段(如 Vite/Webpack)完成工作,而非在浏览器运行时。
阶段二:挂载(Mount)
- 响应式模块初始化响应式对象
- 渲染器调用
render function,引用响应式数据 render function返回 vnode(虚拟 DOM 节点)- 渲染器将 vnode 应用到真实 DOM,页面呈现内容
阶段三:更新(Update)
当响应式数据发生变化时:
- 触发
render function重新执行 - 生成新的 vnode 树
- Diff 算法对比新旧 vnode
- 渲染器的更新模块将差异应用到真实 DOM
完整流程示例
1. 编译阶段
Template: <div>{{ message }}</div>
↓ Compiler
Render Function: function render() { return h('div', this.message) }
2. 挂载阶段
初始化响应式对象 → message = "Hello"
↓
调用 render function → 生成 vnode: { type: 'div', children: 'Hello' }
↓
渲染器挂载到真实 DOM → 页面显示 "Hello"
3. 更新阶段
修改响应式数据 → message = "World"
↓
触发 render function → 生成新 vnode: { type: 'div', children: 'World' }
↓
Diff 对比新旧 vnode → 发现 children 变化
↓
渲染器更新真实 DOM → 页面显示 "World"
text
三大模块的职责分工
| 模块 | 输入 | 输出 | 核心能力 |
|---|---|---|---|
| Reactivity(响应式) | 普通对象 | 响应式对象 | 数据变化时触发副作用 |
| Compiler(编译器) | Template 模板 | Render Function | 编译时优化(静态标记、树摇) |
| Renderer(渲染器) | vnode + 容器 | 真实 DOM | 挂载、更新、卸载 |
模块命名对照
在阅读 Vue 源码或课程时,可能遇到不同的命名方式:
| 课程中可能用到的名称 | 对应源码模块 | 对应渲染管线阶段 |
|---|---|---|
| 编译器 / 编译模块 | compiler-core | Template → vnode |
| 响应式 / 响应式系统 | reactivity | 数据追踪与触发 |
| 渲染器 / 渲染模块 | runtime-core | vnode → 真实 DOM |
理解渲染管线的整体流程后,后续学习 Vue 源码时就拥有了全局视角(上帝视角),能够准确定位每个模块在整个流程中的位置和职责。
相关资源
↑