Vue 的模板编译是 Vue 框架中的一个核心机制,它把我们写的模板(如 <template> 中的 HTML 结构)转换成高效的 JavaScript 渲染函数,最终生成真实的 DOM 或虚拟 DOM。
整体流程概览 🧩
graph LR
模板字符串 --> 解析器Parser --> AST抽象语法树 --> 优化器Optimizer --> 优化后的AST标记静态节点 --> 代码生成器Codegen --> render函数 --> 运行时执行 --> 生成Virtual_DOM --> 更新真实DOM
详细步骤拆解 🔍
解析阶段(Parser)
- 把模板字符串 <template>...</template> 转换为抽象语法树(AST)。
- AST 是一个用来描述模板结构的 JSON 对象,记录每个标签、属性、插值表达式等信息。
例如:
html
<template>
<div class="hello">{{ msg }}</div>
</template>
对应 AST 节点(简化):
json
{
"tag": "div",
"attrs": [{ "name": "class", "value": "hello" }],
"children": [
{ "type": "Interpolation", "content": "msg" }
]
}
优化阶段(Optimizer)
- 作用:标记模板中哪些是静态节点,不需要每次更新时都重新生成。
- 好处:极大提升性能,避免不必要的 diff。
代码生成阶段(Codegen)
- 将 AST 转换为 JavaScript 的 render 函数:
js
function render(ctx) {
return h("div", { class: "hello" }, ctx.msg)
}
这个函数就是运行时执行生成虚拟 DOM 的关键
运行时阶段(执行 render 函数)🚀
- Vue 会执行上一步生成的 render 函数,得到虚拟 DOM(VNode)。
- 最后通过 patch 算法把虚拟 DOM 渲染/更新成真实 DOM。
Vue2 vs Vue3 编译机制差异 🧠
区别 | Vue 2 | Vue 3 |
---|---|---|
编译方式 | 运行时模板编译 or 预编译 | 推荐预编译(更快) |
虚拟 DOM | 手写实现 | 重构成 Proxy + Block Tree |
优化逻辑 | 静态标记不够彻底 | 更强的静态提升和 patch 优化 |
模板入口 | Vue.compile | @vue/compiler-dom 提供完整编译链 |
补充:你可以手动查看模板是如何编译的 🔬
方法一:使用官方在线编译工具
👉 地址:template-explorer.vuejs.org/
粘贴一段模板,它会展示:
- AST 抽象语法树
- 生成的 render 函数
- Vue3 block tree 等优化结果
总结记忆 🔚
阶段 | 作用 |
---|---|
模板解析 | 生成 AST |
静态优化 | 标记静态节点 |
渲染函数生成 | 转为 render 函数 |
虚拟 DOM 创建 | render 执行得到 VNode |
DOM 更新 | patch 虚拟 DOM 到真实 DOM |
如果想深入了解 Vue3 的编译器源码,可以从 @vue/compiler-core 包入手,里面包含了完整的解析、优化、生成等核心模块。
模块 | 说明 |
---|---|
@vue/compiler-core | 编译器核心逻辑(解析、优化、代码生成) |
@vue/compiler-dom | 面向浏览器的模板编译器(使用 compiler-core) |
@vue/compiler-sfc | 处理 .vue 单文件组件 |
@vue/compiler-ssr | SSR 渲染使用的编译器 |
推荐前置知识:
- 熟悉 Vue3 的模板语法(包括指令、插值、条件、循环等)
- 熟悉 AST(抽象语法树)的结构和基本操作
- 熟悉 JavaScript 的递归与字符串处理
- 理解虚拟 DOM 与渲染函数的基本原理