vm.update的时候会执行以下代码
Vue.prototype._update = function (vnode, hydrating) {
if (!prevVnode) {
// initial render
vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);
} else {
// updates
vm.$el = vm.__patch__(prevVnode, vnode);
}
}
vm.patch 在非Server端就是patch
// install platform patch function
Vue.prototype.__patch__ = inBrowser ? patch : noop;
return patch (oldVnode, vnode, hydrating, removeOnly)
以下是patchVnode的代码
function patchVnode (
oldVnode,
vnode,
insertedVnodeQueue,
ownerArray,
index,
removeOnly
) {
if (oldVnode === vnode) {
return
}
if (isDef(vnode.elm) && isDef(ownerArray)) {
// clone reused vnode
vnode = ownerArray[index] = cloneVNode(vnode);
}
var elm = vnode.elm = oldVnode.elm;
var i;
var data = vnode.data;
if (isDef(data) && isDef(i = data.hook) && isDef(i = i.prepatch)) {
i(oldVnode, vnode);
}
var oldCh = oldVnode.children;
var ch = vnode.children;
if (isDef(data) && isPatchable(vnode)) {
for (i = 0; i < cbs.update.length; ++i) { cbs.update[i](oldVnode, vnode); }
if (isDef(i = data.hook) && isDef(i = i.update)) { i(
oldVnode, vnode); }
}
if (isUndef(vnode.text)) {
if (isDef(oldCh) && isDef(ch)) {
// 1
if (oldCh !== ch) { updateChildren(elm, oldCh, ch, insertedVnodeQueue, removeOnly); }
} else if (isDef(ch)) {
{
checkDuplicateKeys(ch);
}
// 3
if (isDef(oldVnode.text)) { nodeOps.setTextContent(elm, ''); }
// 2,3
addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
} else if (isDef(oldCh)) {
//4
removeVnodes(oldCh, 0, oldCh.length - 1);
} else if (isDef(oldVnode.text)) {
//5
nodeOps.setTextContent(elm, '');
}
} else if (oldVnode.text !== vnode.text) {
// 6
nodeOps.setTextContent(elm, vnode.text);
}
if (isDef(data)) {
if (isDef(i = data.hook) && isDef(i = i.postpatch)) { i(oldVnode, vnode); }
}
}
patchVnode的逻辑主要分以下情况(下面的几种情况序号分别对应上面代码的标记处)
关于updateChildren
下面连接的视频大概描述了updateChildren的过程 updateChildren的过程
还有之前写过一篇文章关于 Duplicate keys导致update时报错