详解vue 虚拟dom的patch源码分析

本文详细探讨了Vue框架中虚拟DOM的patch源码分析,通过实例阐述了如何对比并更新新旧两棵树的子节点,以实现高效性能优化。通过对不同情况的逻辑处理,展示了如何在复杂子节点场景下提升更新效率。
摘要由CSDN通过智能技术生成

本文介绍了vue 虚拟dom的patch源码分析,分享给大家,具体如下:
源码目录:src/core/vdom/patch.js

function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) {
 let oldStartIdx = 0
 let newStartIdx = 0
 let oldEndIdx = oldCh.length - 1
 let oldStartVnode = oldCh[0]
 let oldEndVnode = oldCh[oldEndIdx]
 let newEndIdx = newCh.length - 1
 let newStartVnode = newCh[0]
 let newEndVnode = newCh[newEndIdx]
 let oldKeyToIdx, idxInOld, vnodeToMove, refElm
 
   const canMove = !removeOnly
 
 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { // 开始索引大于结束索引,进不了
  if (isUndef(oldStartVnode)) {
   oldStartVnode = oldCh[++oldStartIdx] // Vnode已经被移走了。
  } else if (isUndef(oldEndVnode)) {
   oldEndVnode = oldCh[--oldEndIdx]
  } else if (sameVnode(oldStartVnode, newStartVnode)) {
   patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue)
   oldStartVnode = oldCh[++oldStartIdx] // 索引加1。是去对比下一个节点。比如之前start=a[0],那现在start=a[1],改变start的值后再去对比start这个vnode
   newStartVnode = newCh[++newStartIdx]
     
  } else if (sameVnode(oldEndVnode, newEndVnode)) { 
   patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue)
   oldEndVnode = oldCh[--oldEndIdx]
   newEndVnode = newCh[--newEndIdx]
  } else if (sameVnode(oldStartVnode, newEndVnode)) { 
   patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue)
   canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm))// 把节点b移到树的最右边
   oldStartVnode = oldCh[++oldStartIdx]
   newEndVnode = newCh[--newEndIdx]
     
  } else if (sameVnode(oldEndVnode, newStartVnode)) {  old.end.d=new.start.d
   patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue)
   canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm)// Vnode moved left,把d移到c的左边。=old.start->old.end
   oldEndVnode = oldCh[--oldEndIdx] 
   newStartVnode = newCh[++newStartIdx] 
 
  } else {
   if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
   idxInOld = isDef(newStartVnode.key)
    ? oldKeyToIdx[newStartVnode.key]
    : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx)
   if (isUndef(idxInOld)) { 
    createElm(newStartVnode, insertedVnodeQueue, parentElm, oldStartVnode.elm) // 创建新节点,后面执行了nodeOps.insertBefore(parent, elm, ref)
   } else {
    vnodeToMove = oldCh[idxInOld]
    /* istanbul ignore if */
    if (process.env.NODE_ENV !== 'production' && !vnodeToMove) {
     warn(
      'It seems there are dupli
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值