patchchildren 是 vue 3 根据子节点类型动态选择更新策略的核心机制:文本子节点直接更新 textcontent;数组子节点执行双端 diff;混合类型则全量替换;空子节点执行安全卸载。

PatchChildren 是 Vue 3 内部用于比对和更新虚拟 DOM 子节点的核心策略,它不只是一种方法,而是一组根据子节点类型动态选择的更新路径。理解它,关键在于识别“什么情况下走哪条路”,而不是死记硬背流程。
文本子节点:直接复用或替换文本内容
当新旧 vnode 的 children 都是纯字符串(即没有子元素,只有文本)时,Vue 跳过复杂的 diff,直接调用 hostSetElementText 更新真实 DOM 的 textContent。这最快也最轻量。
常见情况包括:
- 响应式数据变化导致插值表达式重新求值(如
{{ msg }}) - 组件返回纯文本模板(如
return () => 'Hello') - 静态文本被条件逻辑包裹但最终只渲染一段文字
数组子节点:进入核心 diff 算法(快速路径 + 双端对比)
当新旧 children 均为数组(即存在多个子 vnode),Vue 先尝试快速路径:若头尾节点都相同(key 和 type 均一致),就跳过这部分比对,直接 patch 中间节点;否则启动双端对比(从首尾同时向中间推进),高效处理插入、删除、移动等操作。
这个过程依赖 key 的稳定性——无 key 或 key 重复会退化为低效的“就地复用”模式,可能引发状态错乱或动画异常。
混合类型场景:降级为 unkeyed 模式或强制重建
如果新旧 children 类型不一致(比如旧的是数组,新的是字符串;或一方为 null/undefined),Vue 不做 diff,而是直接卸载旧子树、挂载新子树。这种“全量替换”开销较大,应尽量避免在高频更新区域出现。
典型触发点:
- v-if / v-else 切换导致子节点结构类型突变
- 作用域插槽返回不同类型内容(如有时返回列表,有时返回提示文案)
- 函数式组件返回值类型不稳定
空子节点:清空 DOM 并跳过后续逻辑
当新 children 为 null、undefined 或空数组时,Vue 会遍历旧子节点并逐个卸载,调用 unmount 清理事件、定时器、子组件实例等资源。这是安全清理的关键环节,不可跳过。
注意:使用 v-if="false" 和 v-show="false" 在此处行为不同——前者触发卸载(进入此路径),后者仅切换 display 样式,不走 PatchChildren。










