当前位置:首页 > VUE

vue diff实现

2026-01-12 23:22:45VUE

Vue 的 Diff 算法实现

Vue 的虚拟 DOM Diff 算法(称为 "patch" 过程)通过高效比较新旧虚拟节点(VNode)来最小化 DOM 操作。其核心思想是基于以下策略:

同层级比较

Vue 仅在同一层级的虚拟节点间比较,不跨层级递归。若节点类型不同(如 div 变为 span),直接销毁旧节点并创建新节点。

vue diff实现

双端比较(针对列表)

对于列表节点(如 v-for),Vue 使用 双端指针(头尾共 4 个指针)进行快速比对,优先处理以下场景:

  1. 头头匹配:新旧列表的头节点相同。
  2. 尾尾匹配:新旧列表的尾节点相同。
  3. 头尾匹配:旧头与新尾相同(说明节点移动到尾部)。
  4. 尾头匹配:旧尾与新头相同(说明节点移动到头部)。

若无匹配,则通过 key 查找旧节点中是否存在可复用的节点。

vue diff实现

Key 的作用

key 是唯一标识,帮助 Vue 识别节点的稳定性。若 key 相同且节点类型相同,则复用 DOM 元素,仅更新属性或子节点。

核心代码逻辑示例

以下是简化后的 Diff 流程代码(非完整源码):

function patch(oldVnode, newVnode) {
  // 类型不同,直接替换
  if (oldVnode.tag !== newVnode.tag) {
    replaceNode(oldVnode, newVnode);
    return;
  }

  // 复用 DOM 元素
  const el = (newVnode.el = oldVnode.el);

  // 更新属性
  updateProps(el, oldVnode.props, newVnode.props);

  // 处理子节点
  if (oldVnode.children && newVnode.children) {
    updateChildren(el, oldVnode.children, newVnode.children);
  } else if (newVnode.children) {
    // 旧无子,新有子:添加
    appendChildren(el, newVnode.children);
  } else if (oldVnode.children) {
    // 旧有子,新无子:删除
    removeChildren(el);
  }
}

function updateChildren(parentEl, oldCh, newCh) {
  let oldStartIdx = 0, newStartIdx = 0;
  let oldEndIdx = oldCh.length - 1, newEndIdx = newCh.length - 1;

  while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
    // 双端比较逻辑...
    if (sameVnode(oldCh[oldStartIdx], newCh[newStartIdx])) {
      patch(oldCh[oldStartIdx], newCh[newStartIdx]);
      oldStartIdx++;
      newStartIdx++;
    } else if (sameVnode(oldCh[oldEndIdx], newCh[newEndIdx])) {
      patch(oldCh[oldEndIdx], newCh[newEndIdx]);
      oldEndIdx--;
      newEndIdx--;
    }
    // 其他情况处理...
  }
}

性能优化策略

  1. 静态节点提升:编译阶段标记静态节点,Diff 时直接跳过。
  2. 事件缓存:避免重复绑定事件处理函数。
  3. 异步更新队列:通过 nextTick 批量处理 DOM 更新,减少重排重绘。

与 React Diff 的区别

  1. 列表策略:Vue 使用双端比较,React 使用单向遍历。
  2. 组件复用:Vue 通过 key 和组件类型匹配复用,React 仅依赖 key
  3. 移动逻辑:Vue 更擅长处理节点位置变化,React 倾向于按索引顺序更新。

标签: vuediff
分享给朋友:

相关文章

vue实现下载暂停

vue实现下载暂停

Vue实现下载暂停功能 在Vue中实现下载暂停功能,通常需要结合XMLHttpRequest或Fetch API的AbortController来控制请求中断。以下是具体实现方法: 使用XMLHtt…

实现vue

实现vue

安装Vue.js 通过npm安装Vue.js是最常见的方式。确保已安装Node.js和npm,运行以下命令: npm install vue 或者使用CDN直接引入: <script src…

vue 实现pc

vue 实现pc

Vue 实现 PC 端应用的核心要点 Vue.js 是一个渐进式框架,适合构建 PC 端单页应用(SPA)或复杂的前端界面。以下是实现 PC 端应用的关键方法和注意事项: 项目初始化与工程化配置 使…

vue实现语音

vue实现语音

Vue 实现语音功能的方法 使用 Web Speech API Vue 可以结合 Web Speech API 实现语音识别和合成功能。Web Speech API 包含 SpeechRecognit…

computed vue 实现

computed vue 实现

computed 在 Vue 中的基本用法 Vue 的 computed 属性用于声明依赖于其他数据的计算属性。当依赖的数据变化时,计算属性会自动重新计算并缓存结果。 export defaul…

vue observer实现

vue observer实现

Vue Observer 实现原理 Vue 的响应式系统核心是通过 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现的 Observer 模式。以下是关键实现细…