虚拟dom
diff算法 -- diff算法的对象是虚拟dom,更新真实dom是diff算法的结果。
为什么使用虚拟dom
1. DOM操作代价昂贵,可维护性差
2. 虚拟DOM轻量,对虚拟DOM操作快
3. diff算法是找出本次DOM需要更新的节点,不更新的节点进行dom就地复用,可以减少浏览器页面的重绘。
diff算法原理
1. patch原理
patch函数接收6个参数: oldVnode vnode hydrating removeOnly parentElm refElm
patch逻辑:
1.if vnode不存在 oldVnode存在 调用 invokeDestroyHook 销毁节点
2.if oldVnode不存在 vnode存在 调用createElm来创建节点
3. 当vnode 和 oldVnode 都存在 同一个节点 调用patchVnode。 当vnode 和 oldVnode 不是同一个节点,如果oldVnode是真实的dom节点或者hydrating为true,用hydrating函数将虚拟dom和真实dom进行映射,然后将oldVnode设置为对应的虚拟dom,找到oldVnode的父节点,根据vnode创建真实dom插入到父节点中oldVnode.elm的位置。
patchVnode逻辑:
1. 如果oldVnode === vnode 不需要做任何事情
2. 如果oldVnode和vnode都是静态节点 且有相同的key 当vnode是克隆节点或是v-once指令控制的节点,把oldVnode.elm和oldVnode.child都复制到vnode
3. 如果vnode不是文本节点或注释节点 如果oldVnode和vnode都有子节点 节点不一致 调用updateChildren。如果oldVnode只有子节点,则将节点都删除。如果只有vnode有子节点,则创建子节点。如果oldVnode和vnode都没有子节点,但是oldVnode是文本节点或注释节点,就把vnode.elm文本设置成空字符串
<p> 4. 如果vnode是文本节点或注释节点,但vnode.text !==oldVnode.text,只需要更新vnode.elm文本内容就可以了。 </p>
3. diff算法是找出本次DOM需要更新的节点,不更新的节点进行dom就地复用,可以减少浏览器页面的重绘。
</p>