什么是虚拟DOM?
虚拟DOM把真实DOM变成了一个js对象。虚拟DOM用js对象描述DOM的层次结构,DOM中的一切属性都在虚拟DOM中有对应属性。
为何需要虚拟DOM?
因为diff是发生在虚拟DOM上的,新虚拟DOM和老虚拟DOM进行diff(精细化比较),算出应该如何最小量更新,最后反映到真正的DOM上。
什么是snabbdom?
snabbdom 库 是著名的虚拟DOM 库,是diff 算法的鼻祖,Vue源码借鉴了snabbdom 。DOM库不能在nodejs环境运行,所以需要搭建webpack和webpack-dev-server开发环境,不需要安装任何loader
注:webpack4没有读取身份证中exports的能力,webpack5才开始支持这个能力
虚拟DOM如何被渲染函数(h函数)产生?
h函数是用来参生虚拟节点的。h函数可以嵌套使用,从而得到虚拟DOM树
h函数其实主要执行了vnode函数。根据传入h函数的参数来决定执行vnode函数时传入的参数。而vnode函数功能就是把传入的5个参数组成合成对象,即虚拟DOM。然后h函数再把这个虚拟DOM返回。
一个虚拟节点都有哪些属性?
{
children: undefined, // 子元素
data: {}, // 节点的属性、样式
elm: undefined, // 对应真正DOM节点,如果为undefined,表示该节点还未上树
key: undefined, // 节点唯一标识
sel: "div", // 选择器
text: "我是一个盒子" // 文字
}
diff算法
- diff算法:最小量更新。不会让一样的重新变,而是只变要变的。(一定要加key才能这样!)
- key是节点的唯一标识,服务于最小量更新。
- 只有是同一个虚拟节点(同一虚拟节点即选择器和key都相同),才能进行精细化比较,否则就是暴力删除旧的、插入新的。
- 只进行同层比较,不会进行跨层比较。即使是同一片虚拟节点,但是跨层了就会暴力删除旧的、然后插入新的。
diff算法比对
Patch函数
比较的第一步
patchVnode函数
对比同一个虚拟节点
diff算法的四种命中查找:
新前与旧前
新后与旧后
新后与旧前(此种发生了,涉及移动节点,那么新前指向的节点,移动的旧后之后)
新前与旧后(此种发生了,涉及移动节点,那么新前指向的节点,移动的旧后之前)
命中一种就不在进行命中判断,如果都没命中就开始循环查找了
新增的情况:
删除的情况:
如果新节点先循环完毕老节点还有剩余节点,那它们就是要被删除的节点
复杂的情况: