虚拟DOM
含义:虚拟dom是一个js对象,用来描述真实dom的层次结构,真实dom中的一切属性都能在虚拟dom中有对应的属性
虚拟dom的结构
{
children: undefined // 包含的子节点
data: {} // 属性
elm: undefined // DOM树中的位置
key: undefined // 节点key值
sel: 'div' // 节点标签(select)
text: 'hello world' // 文本
}
虚拟dom的作用
传统dom数据发生变化时,我们需要不断操作dom才能进行数据更新,而虚拟dom会根据当前dom对象的数据生成一个描述当前dom结构的虚拟dom,当数据发生变化时,会生成一个新的虚拟dom,然后通过diff算法比较两个虚拟dom的异同,得出一个最优的更新方法,提高Vue的渲染效率。
snabbdom
一个虚拟dom工具库,能够帮助我们进一步理解虚拟dom的工作原理。
snabbdom主要提供了如下的几个函数
- h函数
- patch函数
- patchVnode函数
- updateChildren函数
export default new Vue({
render:h=>h(App)
}).$mounted('#root')
h函数在render函数内运行,主要作用调用的Vnode函数,根据当前dom生成虚拟dom。
Vnode函数
下面我们来总结一下Vue生成虚拟dom的过程,代码初次运行时,当生命周期走到created->beforeMounted之间时,会调用render函数,render函数会调用h函数,h函数内部会调用Vnode函数,生成虚拟dom。
diff算法
key
用于服务最小化更新- 只有是同一个虚拟节点才会进行精确化比较,选择器相同而且
key
相同才是同一个虚拟节点- 只会进行同层比较,不会进行跨层比较
diff算法优化策略
- 新虚拟列表的前指针(下标) ---- 新前指针
- 新虚拟列表的后指针(下标) ---- 新后指针
- 旧虚拟列表的前指针(下标) ---- 旧前指针
- 旧虚拟列表的后指针(下标) ---- 旧后指针
四种命中规则
- 新前指针 VS 旧前指针
- 新后指针 VS 旧后指针
- 新后指针 VS 旧前指针 (此种情况命中,涉及移动节点,那么新前指针指向的节点,移动到旧后节点之后)
- 旧后指针 VS 新前指针 (此种情况命中,涉及移动节点,那么新前指针指向的节点,移动到旧前节点之前)
命中规则图解