越来越受欢迎的Vue想学么,90后小姐姐今儿来教你 (6)

越来越受欢迎的Vue想学么,90后小姐姐今儿来教你

比对的图变成这样:

越来越受欢迎的Vue想学么,90后小姐姐今儿来教你

继续比对:
li(b)和li(b)的key相同,patch,都是前指针相同所以不移动,移动指针
这个时候前指针就在后指针后面了,这个比对就结束了。

越来越受欢迎的Vue想学么,90后小姐姐今儿来教你

这就完成了常规的比对,还有不常规的,如下图:

越来越受欢迎的Vue想学么,90后小姐姐今儿来教你

经过1,2,3,4次比对后发现,没有相同的key值能够移动。

这种情况我们没有办法,只有用老办法,用newStartIndex的key拿去依次到prev里的vnode,直到找到相同key值的老的vnode,先patch,然后获取真实dom移动到正确的位置(放到oldStartIndex前面),然后在prevChildren中把移动过后的vnode设置为undefined,在下次指针移动到这里的时候直接跳过,并且next的start指针向右移动。

function updateChildren (elm, prevChildren, nextChildren) { let oldStartIndex = 0; let oldEndIndex = prevChildren.length - 1; let newStartIndex = 0; let newEndIndex = nextChildren.length - 1; while (oldStartIndex <= oldEndIndex && newStartIndex <= newEndIndex) { let oldStartVnode = prevChildren[oldStartIndex]; let oldEndVnode = prevChildren[oldEndIndex]; let newStartVnode = nextChildren[newStartIndex]; let newEndVnode = nextChildren[newEndIndex]; if (oldStartVnode === undefined) { oldStartVnode = prevChildren[++oldStartIndex]; } if (oldEndVnode === undefined) { oldEndVnode = prevChildren[--oldEndIndex]; } if (oldStartVnode.key === newStartVnode.key) { patchVnode(newStartVnode, oldStartVnode); oldStartIndex++; newStartIndex++; } else if (oldEndVnode.key === newEndVnode.key) { patchVnode(newEndVnode, oldEndVnode); oldEndIndex--; newEndIndex--; } else if (oldStartVnode.key === newEndVnode.key) { patchVnode(newEndVnode, oldStartVnode); elm.insertBefore(oldStartVnode.elm, oldEndVnode.elm.nextSibling); newEndIndex--; oldStartIndex++; } else if (oldEndVnode.key === newStartVnode.key) { patchVnode(newStartVnode, oldEndVnode); elm.insertBefore(oldEndVnode.elm, oldStartVnode.elm); oldEndIndex--; newStartIndex++; } else { const idxInOld = prevChildren.findIndex(child => child.key === newStartVnode.key); if (idxInOld >= 0) { elm.insertBefore(prevChildren[idxInOld].elm, oldStartVnode.elm); prevChildren[idxInOld] = undefined; newStartIndex++; } } } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfxfy.html