vue diff算法核心是“只比同层、复用靠key”:同层比较避免跨级误判与递归开销;双端指针按头头、尾尾、头尾、尾头顺序快速对齐;key唯一稳定才能正确复用dom;同类型节点仅就地patch不重建。

Vue 的 Diff 算法不是“逐个对比所有节点”,而是用一套有约束、有优先级的策略,把 DOM 更新控制在最小范围内。核心就两点:只比同层、复用靠 key。
同层比较:不跨级,不递归
父节点一旦被替换,整棵子树直接卸载重建,不会尝试把深层节点“捞上来”复用。这样避免了跨层级误判(比如把 <div><p>A</p></div> 和 <section><span>A</span></section> 的 p 与 span 错配),也省去了深度遍历的开销。
这意味着:
- 组件内部状态(如 ref、v-model 绑定值)只在同组件实例内延续,换组件就重来;
- 嵌套列表里,外层 v-for 变了,内层哪怕内容完全一样,也会整体重新渲染;
- 写模板时,避免无意义的 wrapper 元素(如纯 div 包裹),否则可能意外打断同层结构。
双端指针:头尾快速对齐
面对两个子节点数组,Vue 不从头到尾扫一遍,而是用四个指针(旧头、旧尾、新头、新尾)同时推进,优先处理明显一致或位移的节点。
匹配顺序固定为:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 新头 === 旧头 → 直接 patch,两个头往后挪;
- 新尾 === 旧尾 → 直接 patch,两个尾往前挪;
- 新头 === 旧尾 → 把旧尾 DOM 移到新头位置,旧尾前移、新头后移;
- 新尾 === 旧头 → 把旧头 DOM 移到新尾位置,旧头后移、新尾前移。
这四步能覆盖顺序微调、末尾追加/删除等高频场景,大部分情况下不用进查找环节。
key 是复用的唯一通行证
没有 key,Vue 就按索引硬对——第 0 个对第 0 个,第 1 个对第 1 个。一旦插入、删除或排序,input 光标乱跳、滚动位置丢失、动画中断,全是因为 DOM 被错位复用了。
正确用法强调三点:
- key 必须唯一且稳定:用数据项的 id,不用 index 或 random;
- key 相同 + 标签名相同 → 复用 DOM 并 patch 属性/子内容;
- key 相同 + 标签名不同 → 不复用,直接替换整个元素。
就地 patch:同类型节点不重建
如果两个 vnode 都是 <div>,且 key 一致,Vue 不删掉再建一个 div,而是只更新 class、style、事件绑定、文本内容或子 vnode。
<p>这种“打补丁”式更新意味着:</p>
<ul>
<li>input 框保留焦点和输入值;</li>
<li>video 元素维持播放状态;</li>
<li>自定义组件实例不销毁,生命周期钩子不触发 created/mounted;</li>
<li>只有 tag、is、ref 等关键字段变了,才会走 replace 流程。</li>
</ul>
</div>
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










