vue3 动态节点与静态节点

33 阅读1分钟

下面按编译器视角给出判定规则(Vue 3):

  • 静态节点(不会参与更新)
  • 纯静态 HTML:不含 mustache 插值、无 v- 指令、无 :/@ 绑定。
  • 所有属性均为字面量(如 class="a"、style="color:red")。
  • 子树也必须全静态,编译器会整棵“静态提升”(hoist),更新时完全跳过。
  • 动态节点(会被收集进 block 的 dynamicChildren)
  • 动态文本/插值:{{ msg }} → TEXT
  • 动态类/样式::class="x"、:style="y" → CLASS/STYLE
  • 动态属性::id="x"、v-bind="obj" → PROPS/FULL_PROPS
  • 事件绑定:@click="onClick"(值变化需 patch)
  • 表单与双向绑定:v-model
  • 条件与循环:v-if/else-if/else、v-for → 产生动态 Fragment(KEYED/UNKEYED/STABLE)
  • 动态组件与异步组件:<component :is="Comp">、defineAsyncComponent
  • 插槽(含依赖响应式或带 slot props):→ DYNAMIC_SLOTS
  • 特殊容器:Teleport、KeepAlive 内部多为动态子树
  • 实用判断(经验法则)
  • 模板里只要出现 {{}}、v- 指令、:/@、或结构指令(v-if/v-for),基本就是动态。
  • 完全没有上述元素且子节点也满足,则是静态,可被整体 hoist。
  • 编译产物侧标识
  • 有 PatchFlag(如 TEXT/CLASS/PROPS…)→ 动态。
  • 标记为 HOISTED 的 vnode/子树 → 静态,更新跳过。