经过同层的树节点进行比较而非对树进行逐层搜索遍历的方式,因此时间复杂度只有O(n),是一种至关高效的算法node
同层级只作三件事:增删改。
具体规则是:算法
- new VNode不存在就删;
- old VNode不存在就增;
- 都存在就 比较类型,类型不一样直接替换、类型相同执行更新
两个VNode类型相同,就执行更新操做,包括三种类型操做:属性更新PROPS、文本更新TEXT、子节点更新REORDER dom
若是新旧VNode都是静态的,那么只须要替换elm以及componentInstance便可。 spa
新老节点均有children子节点,则对子节点进行diff操做,调用updateChildren 3d
若是老节点没有子节点而新节点存在子节点,先清空老节点DOM的文本内容,而后为当前DOM节 code
点加入子节点。 component
当新节点没有子节点而老节点有子节点的时候,则移除该DOM节点的全部子节点。 cdn
当新老节点都无子节点的时候,只是文本的替换。 blog
首先oldStartVnode、oldEndVnode
与newStartVnode、newEndVnode
两两交叉比较(1-4) 接口
oldStartVnode
和
newStartVnode
知足
sameVnode
,直接将该
VNode
节点进行
patchVnode
便可,不需再遍历就完成了一次循环
oldEndVnode
和
newEndVnode
知足
sameVnode
,直接将该
VNode
节点进行
patchVnode
便可,不需再遍历就完成了一次循环
oldStartVnode
与
newEndVnode
知足
sameVnode
。说明
oldStartVnode
已经跑到了
oldEndVnode
后面去了,进行
patchVnode
的同时还须要将真实DOM节点移动到
oldEndVnode
的后面。
oldEndVnode
与
newStartVnode
知足
sameVnode
,说明
oldEndVnode
跑到了
oldStartVnode
的前面,进行
patchVnode
的同时要将
oldEndVnode
对应DOM移动到
oldStartVnode
对应DOM的前面。
newStartVnode
知足
sameVnode
的
vnodeToMove
,若 存在执行patchVnode,同时将
vnodeToMove
对应DOM移动到
oldStartVnode
对应的DOM的前面。
newStartVnode
在old VNode节点中找不到一致的key,或者是即使key相同却不是
sameVnode
,这个时候会调用
createElm
建立一个新的DOM节点放到old VNode最前面。
oldStartIdx > oldEndIdx
,这个时候旧的VNode节点已经遍历完了,可是新的节点尚未。说 明了新的VNode节点实际上比老的VNode节点多,须要将剩下的VNode对应的DOM插入到真实DOM 中,此时调用
addVnodes
(批量调用createElm接口)。
newStartIdx > newEndIdx
时,说明新的VNode节点已经遍历完了,可是老的节点还有 剩余,须要从文档中删 的节点删除。