If we figure out these two graphs, does diff still work?
FIG. 1
Figure 2
The patch function
function patch (oldVnode, vnode, parentElm) {
if(! oldVnode) { addVnodes(parentElm,null, vnode, 0, vnode.length - 1);
} else if(! vnode) { removeVnodes(parentElm, oldVnode,0, oldVnode.length - 1);
} else {
if (sameVnode(oldVNode, vnode)) {
patchVnode(oldVNode, vnode);
} else {
removeVnodes(parentElm, oldVnode, 0, oldVnode.length - 1);
addVnodes(parentElm, null, vnode, 0, vnode.length - 1); }}}Copy the code
PatchVnode function
function patchVnode (oldVnode, vnode) {
if (oldVnode === vnode) {
return;
}
if (vnode.isStatic && oldVnode.isStatic && vnode.key === oldVnode.key) {
vnode.elm = oldVnode.elm;
vnode.componentInstance = oldVnode.componentInstance;
return;
}
const elm = vnode.elm = oldVnode.elm;
const oldCh = oldVnode.children;
const ch = vnode.children;
if (vnode.text) {
nodeOps.setTextContent(elm, vnode.text);
} else {
if(oldCh && ch && (oldCh ! == ch)) { updateChildren(elm, oldCh, ch); }else if (ch) {
if (oldVnode.text) nodeOps.setTextContent(elm, ' ');
addVnodes(elm, null, ch, 0, ch.length - 1);
} else if (oldCh) {
removeVnodes(elm, oldCh, 0, oldCh.length - 1)}else if (oldVnode.text) {
nodeOps.setTextContent(elm, ' ')}}}Copy the code
UpdateChildren function
function updateChildren (parentElm, oldCh, newCh) {
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, elmToMove, refElm;
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
if(! oldStartVnode) { oldStartVnode = oldCh[++oldStartIdx]; }else if(! oldEndVnode) { oldEndVnode = oldCh[--oldEndIdx]; }else if (sameVnode(oldStartVnode, newStartVnode)) {
patchVnode(oldStartVnode, newStartVnode);
oldStartVnode = oldCh[++oldStartIdx];
newStartVnode = newCh[++newStartIdx];
} else if (sameVnode(oldEndVnode, newEndVnode)) {
patchVnode(oldEndVnode, newEndVnode);
oldEndVnode = oldCh[--oldEndIdx];
newEndVnode = newCh[--newEndIdx];
} else if (sameVnode(oldStartVnode, newEndVnode)) {
patchVnode(oldStartVnode, newEndVnode);
nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm));
oldStartVnode = oldCh[++oldStartIdx];
newEndVnode = newCh[--newEndIdx];
} else if (sameVnode(oldEndVnode, newStartVnode)) {
patchVnode(oldEndVnode, newStartVnode);
nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
oldEndVnode = oldCh[--oldEndIdx];
newStartVnode = newCh[++newStartIdx];
} else {
let elmToMove = oldCh[idxInOld];
if(! oldKeyToIdx) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); idxInOld = newStartVnode.key ? oldKeyToIdx[newStartVnode.key] :null;
if(! idxInOld) { createElm(newStartVnode, parentElm); newStartVnode = newCh[++newStartIdx]; }else {
elmToMove = oldCh[idxInOld];
if (sameVnode(elmToMove, newStartVnode)) {
patchVnode(elmToMove, newStartVnode);
oldCh[idxInOld] = undefined;
nodeOps.insertBefore(parentElm, newStartVnode.elm, oldStartVnode.elm);
newStartVnode = newCh[++newStartIdx];
} else{ createElm(newStartVnode, parentElm); newStartVnode = newCh[++newStartIdx]; }}}}if (oldStartIdx > oldEndIdx) {
refElm = (newCh[newEndIdx + 1])? newCh[newEndIdx +1].elm : null;
addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx);
} else if(newStartIdx > newEndIdx) { removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx); }}Copy the code