Q9
★ ★ ★ ★ ★
Vue 3 的模板是如何编译的?
⚡ 速记答案(30 秒)
1. 解析(parse):template → AST。2. 优化(optimize):标记静态节点/静态子树。3. 代码生成(codegen):AST → render 函数。
📖 详细讲解
标准面试回答(推荐记住)
Vue 3 模板编译分三步:首先 parse 阶段把模板字符串解析成 AST 抽象语法树;然后 optimize 阶段标记静态节点和静态子树,方便后续 diff 跳过;最后 codegen 阶段将 AST 转换为 render 函数代码,内部使用 h() 创建 VNode。
编译流程详解
Parse(解析)
- 将模板字符串解析为 AST(抽象语法树)。
- 处理 HTML 标签、属性、文本、插值表达式等。
Transform (转换/优化)
- Static Hoisting (静态提升):将纯静态节点/属性提升到 render 函数外,避免每次渲染重复创建。
- PatchFlags (补丁标记):分析节点动态部分(如 class、text、props),打上数字标记。
- Block Tree:配合 openBlock,收集动态节点到 dynamicChildren 数组,diff 时只比对这些节点。
Codegen(代码生成)
- 遍历 AST,生成最终的 JS 代码字符串(即 render 函数)。
_createVNode、_openBlock等辅助函数被引入。
✅ 面试要点
- •理解编译的三个阶段
- •知道 AST 的基本结构
- •了解静态提升的作用
💻 代码示例
编译过程示意
// 1. 模板字符串
const template = '<div :class="cls">{{ msg }}</div>'
// 2. 解析为 AST
const ast = {
type: 'Element',
tag: 'div',
props: [{ type: 'Directive', name: 'bind', arg: 'class', exp: 'cls' }],
children: [{ type: 'Interpolation', content: 'msg' }]
}
// 3. 生成 render 函数
function render(_ctx) {
return h('div', { class: _ctx.cls }, toDisplayString(_ctx.msg))
}