Vue 3 编译器在模板编译阶段识别并提升完全静态的属性,使其脱离 runtime patch 流程;静态属性指值恒定、不依赖响应式状态、不含插值或动态指令的 HTML 属性,如 class="btn"、disabled 等。

Vue 3 的编译器会在模板编译阶段识别出**完全静态的属性(static props)**,并将它们直接提升到 vnode 创建之外,从而让 runtime 的 patch 过程无需比对、更新——也就是真正“视而不见”。这背后不是魔法,而是编译时的确定性分析与代码生成策略。
什么是静态属性?
静态属性指那些在组件整个生命周期中值恒定不变、不依赖响应式状态、不含插值表达式、也不含指令动态参数的 HTML 属性。例如:
-
class="btn primary"✅(纯字符串) -
id="submit-btn"✅ -
disabled(布尔属性,无值即存在)✅ -
:class="'btn'"✅(静态字符串字面量,带绑定但无变量) -
:id="`item-${index}`"❌(含响应式变量index) -
v-show="visible"❌(指令绑定响应式变量) -
:style="{ color: textColor }"❌(依赖响应式数据)
编译器如何提取并提升静态属性?
Vue 3 的模板编译器(@vue/compiler-dom)在 parse → transform → generate 流程中,会对每个 element 节点做静态属性标记(staticProps):
审查 Vue 管理后台的变更请求(Vue 2 + Element UI,Vue 3 + Element Plus)。重点关注最小化变更实现、上线风险检查以及回归检查清单生成。
- 遍历所有 attribute 和 directive,判断是否满足静态条件;
- 将所有静态属性聚合成一个 plain object(如
{ class: "btn", id: "ok", disabled: "" }); - 在生成
createVNode调用时,把该对象作为第二个参数(props)直接传入,且不包裹在响应式依赖收集或 patch 更新逻辑中; - 非静态属性则保留在第三个参数(children)或通过
patchFlag标记为动态,进入 diff 流程。
如何写出更容易被提取的静态属性?
你不需要手动优化编译输出,但可以调整写法,帮编译器更准确识别静态性:
立即学习“前端免费学习笔记(深入)”;
- 避免在绑定中使用变量:用
class="a b"替代:class="'a b'"(后者虽静态,但触发额外 binding 分析); - 布尔属性优先写原生形式:
required比:required="true"更易被识别为静态; - 不要混用静态与动态 class/style:
class="btn" :class="isActive ? 'active' : ''"会让整个class被判为动态; - 使用
v-bind批量绑定时需谨慎:v-bind="{ id: 'x', class: 'y' }"中只要一个值动态,全部失效——拆成独立属性更利于静态提取。
验证是否成功“视而不见”?
可在 devtools 的 Compiler Output 面板查看生成代码,或检查打包后的 render 函数:
- 若看到
createVNode("div", { class: "static", id: "foo" }, [...])—— 静态 props 已提升; - 若看到
createVNode("div", { class: _ctx.staticClass }, [...])或带PATCH_FLAG_DYNAMIC_PROPS—— 该属性进入 patch 流程; - 运行时可通过
console.log(vnode.patchFlag)查看标志位,0表示无动态标识,大概率是全静态 vnode。

















