开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第21天,点击查看活动详情
创建节点步骤
真正创建节点,将vnode创建为DOM,是孤儿节点,不会进行插入
创建一个DOM节点
判断有子节点还是有文本节点
内部是文字 document.innerText = vnode.text;
内部如果是子节点,就要递归创建节点
循环得到这个虚拟节点的children属性
创建出DOM使用createElement,创建出DOM,他的ele属性指向DOM
最后将创建的节点appendChild到 创建的节点上
vnode.elm = DOM;
返回elm,elm属性是一个纯DOM对象 return vnode.elm;
对比同一个虚拟节点步骤
判断新旧vnode有没有text属性
如果新vode有text属性
如果新虚拟节点中的text和老的虚拟节点的text,那么直接让新的text写入老的elm中,
如果老的elm是children,则立即会消失
如果新的vode没有text属性,有children
//判断老的有没有children
//老的有children,新的也有children
老的没有children,新的有children,清空老的节点内容
//遍历新的vnode的子节点,创建DOM,最后appendChild上
断是否为同一个虚拟节点
当新后与旧前命中的时候,此时要移动节点,移动前新指向的这个节点到老节点的旧后的后面
如何移动节点?
只要插入一个已经在DOM树上的节点,它就会被移动
制作keyMap一个映射对象,这样不用每次遍历老对象
寻找当前这项,这项在keyMap中的映射的位置序号
判断如果是undefined表示为全新的项
被加入的项不是真正的DOM节点
如果不是undefined,不是全新的项,则要移动
移动: 使用insertBefore可以实现移动
指针下移,只移动新的头
如果循环结束start比old小
则遍历新的newCh,添加到来的没有处理之前
newCh[i]此时还没有真正的变DOM,则需要调用createElement变成真正的DOM
如果start比old大
则批量删除oldStart和oldEnd指针之间的项