📚前端面试题速记
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。

编译流程详解

  1. Parse(解析)

    • 将模板字符串解析为 AST(抽象语法树)。
    • 处理 HTML 标签、属性、文本、插值表达式等。
  2. Transform (转换/优化)

    • Static Hoisting (静态提升):将纯静态节点/属性提升到 render 函数外,避免每次渲染重复创建。
    • PatchFlags (补丁标记):分析节点动态部分(如 class、text、props),打上数字标记。
    • Block Tree:配合 openBlock,收集动态节点到 dynamicChildren 数组,diff 时只比对这些节点。
  3. 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))
}