1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| function patchKeyedChildren(n1,n2,container) { const oldChildren = n1.children const newChildren = n2.children let oldStartIdx = 0 let oldEndIdx = oldChildren.length-1 let newStartIdx = 0 let newEndIdx = newChildren.length-1 let oldStartVnode = oldChildren[oldStartIdx] let oldEndVnode = oldChildren[oldEndIdx] let newStartVnode = newChildren[newStartIdx] let newEndVnode = newChildren[newEndIdx] while(oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { if(!oldStartVnode) { oldStartVnode = oldChildren[++oldStartIdx] }else if(!oldEndVnode){ oldEndVnode = oldChildren[--oldEndIdx] } else if(oldStartVnode.key === newStartVnode.key){ patch(oldStartVnode,newStartVnode,container) oldStartVnode = oldChildren[++oldStartIdx] newStartVnode = newChildren[++newStartIdx] } else if(oldEndVnode.key === newEndVnode.key){ patch(oldEndVnode,newEndVnode,container) oldEndVnode = oldChildren[--oldEndIdx] newEndVnode = newChildren[--newEndIdx] }else if(oldStartVnode.key === newEndVnode.key){ patch(oldStartVnode,newEndVnode,container) insert(oldStartVnode.el,container,oldEndVnode.el.nextSibling) oldStartVnode = oldChildren[++oldStartIdx] newEndVnode = newChildren[--newEndIdx] }else if(oldEndVnode.key === newStartVnode.key){ patch(oldEndVnode,newStartVnode,container) insert(oldEndVnode.el,container,oldStartVnode.el) oldEndVnode = oldChildren[--oldEndIdx] newStartVnode = newChildren[++newStartIdx] }else { const idxInOld = oldChildren.findIndex( node=>node.key===newStartVnode.key ) if(idxInOld > 0){ const vnodeToMove = oldChildren[idxInOld] patch(vnodeToMove,newStartVnode,container) insert(vnodeToMove.el,container,oldStartVnode.el) oldChildren[idxInOld] = undefined
}else{ patch(null,newStartVnode,container,oldStartVnode.el) } newStartVnode = newChildren[++newStartIdx] } } if(oldEndIdx < oldStartIdx && newStartIdx <= newEndIdx){ for(let i = newStartIdx; i<=newEndIdx ; i++){ patch(null,newChildren[i],container,oldStartVnode.el) } } if(newEndIdx < newStartIdx && oldStartIdx<=oldEndIdx) { for(let i=oldStartIdx;i<oldEndIdx;i++){ unmount(oldChildren[i]) } }
} function insert(el,parent,anchor=null){ parent.insertBefore(el,anchor) }
|