Vue diff原理
灵感来源
Vitrual DOM与真实DOM
详解
仅在同层比较,不会跨层级比较

流程图

代码部分
patch
patchVnode
updateChildern(核心)




最后更新于






最后更新于
<div>
<p>123</p>
</div>var Vnode = {
tag: "div",
children: [{ tag: "p", text: "123" }]
};function patch(oldVnode, vnode) {
// some code
if (sameVnode(oldVnode, vnode)) {
patchVnode(oldVnode, vnode);
} else {
const oEl = oldVnode.el; // 当前oldVnode对应的真实元素节点
let parentEle = api.parentNode(oEl); // 父元素
createEle(vnode); // 根据Vnode生成新元素
if (parentEle !== null) {
api.insertBefore(parentEle, vnode.el, api.nextSibling(oEl)); // 将新元素添加进父元素
api.removeChild(parentEle, oldVnode.el); // 移除以前的旧元素节点
oldVnode = null;
}
}
// some code
return vnode;
}patchVnode (oldVnode, vnode) {
const el = vnode.el = oldVnode.el
let i, oldCh = oldVnode.children, ch = vnode.children
if (oldVnode === vnode) return
if (oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text) {
api.setTextContent(el, vnode.text)
}else {
updateEle(el, vnode, oldVnode)
if (oldCh && ch && oldCh !== ch) {
updateChildren(el, oldCh, ch)
}else if (ch){
createEle(vnode) //create el's children dom
}else if (oldCh){
api.removeChildren(el)
}
}
}oldS = a, oldE = d;S = a, E = b;oldS = b, oldE = d;S = c, E = b