vue.js编译器在编译期通过静态分析和表达式求值折叠内联常量表达式,满足“纯静态、无依赖、无副作用”条件的表达式(如字面量组合、全局白名单对象调用、简单常量标识符、常量分支三元/逻辑运算)被直接替换为字面量,提升运行时性能。

Vue.js 编译器识别并内联常量表达式,核心在于编译期静态分析 + 表达式求值折叠,不是运行时判断。它把能提前算出结果的表达式直接替换成字面量,省去每次渲染时的重复计算。
哪些表达式会被识别为常量
满足“纯静态、无依赖、无副作用”三个条件的表达式才会被内联:
- 字面量组合:{{ 1 + 2 }}、{{ 'hello' + 'world' }}、{{ true && false }}
- 全局白名单对象调用:{{ Math.PI }}、{{ JSON.stringify({a:1}) }}、{{ new Date().getFullYear() }}(注意:仅限编译期可确定结果的调用)
- 简单标识符引用:如果变量在编译期被明确标记为常量(如 defineProps 中的静态默认值、
const声明且未被重赋值),且上下文无响应式污染,也可能参与折叠 - 三元/逻辑运算中的常量分支:{{ true ? 'yes' : 'no' }} → 直接内联为 'yes';{{ false && obj.name }} → 内联为 false
编译器如何实现常量折叠
这一过程主要由 transformExpression 插件完成,关键步骤如下:
- 解析插值或指令中的 JS 表达式,生成 AST
- 递归遍历 AST 节点,检查每个子表达式是否为字面量(
isLiteral)、是否引用了不可变的全局对象(如Math、JSON)、是否包含禁止操作(如赋值、函数声明、this引用等) - 对可安全求值的子树调用
evaluate函数(内部使用轻量 JS 求值器),得到运行结果 - 将原 AST 节点替换为对应字面量节点,并标记
node.constType = ConstantTypes.CAN_STRINGIFY - 最终在生成渲染函数代码时,直接输出字符串、数字或布尔值,而非保留表达式调用
内联后的实际效果
比如模板中写:
<div>{{ 2 * Math.PI.toFixed(2) }}</div>
编译后不会生成 2 * Math.PI.toFixed(2) 的运行时调用,而是:
<div>6.28</div>
对应 JS 渲染代码里就是普通字符串节点,不涉及任何运行时计算。
注意事项与边界
以下情况不会被内联:
- 含响应式数据引用:{{ count + 1 }} 中
count是响应式变量 → 保留为运行时表达式 - 含方法调用(即使方法体简单):{{ formatName(name) }} → 不折叠,因无法确认方法是否纯函数或有副作用
- 含
this、arguments、super等动态绑定关键字 - 含
console、alert、fetch等副作用调用 - 复杂对象/数组字面量嵌套过深,或含 computed 属性访问(如 {{ obj?.prop?.value }} 中任意环节可能为 undefined)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










