Vue 3 模板编译器

当我们写下 <div>{{ msg }}</div> 时,浏览器看到的既不是标签,也不是文本,而是一段可执行的 JavaScript 函数。这道转换由 Vue 的模板编译器完成:它把纯文本一步步转化为渲染函数,并在此过程中完成静态提升、指令降级、依赖标记等优化。

一、为什么需要编译器?

  • 声明式语法降低开发负担,开发者只需描述"想要什么"。
  • 运行时性能通过预编译得到保证:静态节点被提升、动态节点被打补丁。
  • 多端统一:同一套模板可输出 DOM、小程序、Canvas 渲染函数。

二、编译器三步流水线概览

  1. 解析 (Parse) 有限状态机把字符串切成 Token,再组装成 AST。
  2. 转换 (Transform) 在 AST 上完成静态提升、表达式提取、指令转换。
  3. 生成 (Generate) 将优化后的 AST 拼接成可执行的渲染函数字符串。

三、解析阶段:有限状态机逐字符扫描

<p>Vue</p> 为例,编译器内部维护一个状态机:

  • 初始状态读到 < → 进入标签开始状态
  • 读到字母 → 收集标签名
  • 读到 > → 完成开始标签,创建 AST 节点并入栈
  • 读到文本 → 创建文本节点挂到栈顶
  • 读到 </ → 结束标签,弹出栈顶节点

每一步都伴随字符消费和状态转移,最终得到结构化 AST:

js 复制代码
{
  type: 'Root',
  children: [{
    type: 'Element',
    tag: 'p',
    children: [{ type: 'Text', content: 'Vue' }]
  }]
}

四、转换阶段:AST 上的优化魔法

Vue 在此阶段完成三项关键优化:

  • 静态提升:不含响应式数据的节点被提升到渲染函数外部,避免重复创建。
  • 表达式提取:{{ msg }} 被编译为 _ctx.msg,运行时直接取值。
  • 指令转换:v-ifv-for 被降维为三元表达式或循环语句,减少运行时分支判断。

五、生成阶段:AST → 渲染函数

遍历优化后的 AST,拼接字符串:

js 复制代码
function generate(ast) {
  return `function render(_ctx) {
    return h('p', _ctx.msg);
  }`;
}

生成的渲染函数可直接 new Function(code) 实例化,运行时零解析开销。

工程意义

  • 编译时优化:PatchFlag、Block Tree 把 diff 复杂度降到 O(n)。
  • Tree-Shaking:未使用语法在编译阶段删除,减小包体积。
  • 多端渲染:同一套 AST 可以生成 DOM、小程序、Canvas 渲染函数。
相关推荐
Rain的Java大神之路3 小时前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
百万蹄蹄向前冲4 小时前
风扇转了一晚上MVP专家团翻车事故
前端·人工智能
默_笙4 小时前
🏛 给 AI 配一间办公室:Harness Engineering 六大模块与它的实现
前端·javascript
淡海水4 小时前
13-04-面试-源码级深度追问链
数据结构·unity·面试·c#·游戏引擎·源码·il2cpp
linux_cfan5 小时前
videojs v10 源代码系列解读:14 · 谓词守卫:在运行时安全地调用能力
前端·javascript·音视频
kyriewen6 小时前
我扒了 10,221 条 JD:腾讯技术岗 75% 在要 AI
前端·人工智能·ai编程
郑州光合科技余经理6 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
+VX:Fegn08957 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
雪芽蓝域zzs7 小时前
第 7 章:双 Y 轴组合图(柱状 + 折线,看板高频场景)
vue.js·echars
IT_陈寒7 小时前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端