// vnode => dom 虚拟dom => 真实的dom(vue初始渲染)
// patch与diff算法 http://www.lanlanwork.com/blog/?post=6056
// 初始渲染 根据虚拟dom创建出元素,将该元素的子元素和属性逐个添加到这个元素上面,形成真实dom
function createElement(vnode) {
// 目标对象 ul div
let tag = vnode.tag;
// 目标对象的属性 有可能没有属性 所以给个空对象
let attrs = vnode.attrs || {};
// 目标对象的子节点,没有的给个空数组
let children = vnode.children || [];
// 如果连tag目标对象都没有,返回null
if (!tag) {
return null;
}
// 创建元素
let elem = document.createElement(tag),
attrName;
// 给元素赋值属性
for (attrName in attrs) {
// 判断目标对象是否存在属性名称
if (attrs.hasOwnProperty(attrName)) {
// 存在 给elem添加 属性
elem.setAttribute(attrName, attrs[attrName])
}
}
// 添加子元素 深层次递归
children.forEach(childVnode => {
elem.appendChild(createElement(childVnode))
});
// 真实的dom
return elem;
}
// 节点更新 新节点替换老节点 找到变化的节点或子节点进行替换,深层次递归,直到找到差异
function updateChildren(vnode, newVnode) {
let children = vnode.children || [];
let newChildren = newVnode.children || [];
// 遍历现有的children 的子节点childVnode 和它的下标index
children.forEach((childVnode, index) => {
// 获取新节点的index这个 进行比较
let newChildVnode = newChildren[index];
n
// 如果相同
if (childVnode.tag === newChildVnode.tag) {
// 深层次递归
updateChildren(childVnode, newChildVnode);
} else {
// 不同 替换
replaceNode(childVnode, newChildVnode);
}
})
}