今天翻看了vue.js设计和实现的第九章内容,主要是谈论Dom的Diff算法。因为实际操作dom的开销很大,所以有dom的Diff算法来减小操作dom的次数,来提高性能。
一.比较标签元素
通过比较标签的元素,来减少操作dom的次数。只要新旧子节点中的标签相同,我们就只更新节点的内容就可以
二.新旧子节点的数量不同
第一点中,我们默认了新旧子节点的数量是一样的,但是实际中我们可以要卸载或挂载上节点。这时候我们应该比较新旧节点的数量,遍历数量少的那一组节点,然后再判断剩余节点是应该挂载上还是卸载掉
三.Dom复用和key
如果新旧子节点的标签相同,只是顺序不一样。难道我们还应该在全部卸载再挂载上去吗?其实我们只需要移动节点的顺序,便可达到同样的效果。但是移动的前提是我们必须找到可以复用的子节点,所以我们要进行一轮对比操作,判断旧的子节点中有没有可以复用的。假如我们还是通过标签的方式来进行判断,若新旧子节点中的标签是一样的,那么我们无法知道这个新节点中的标签对应到旧节点中的标签是哪一个,也就无法得知我们应该如何移动,所以我们引入了key,只要两个虚拟节点的 type 属性值和 key 属性值都相同,那么我们就认为它们是相同的,即可以 进行 DOM 的复用。
四.如何移动
1.找到需要移动的元素
逆向思维,什么时候不需要移动元素。当新旧子节点的顺序相对不变的时候,我们便不需要移动元素。使用lastIndex记录新节点在旧节点中的最大索引值,如果索引值递增的顺序被打破,则需要移动该元素。
2.如何移动
通过改变引用的方式
改变引用后
添加新元素
如果有前一个 vnode 节点,则使用它的下一个兄弟节点作为锚点元素,如果没有前一个 vnode 节点,说明即将挂载的新节点是第一个子节。
删除元素
当基本的更新结束时,我们需要遍历旧的一组子节点,然后去新的一组子节 点中寻找具有相同 key 值的节点。如果找不到,则说明应该删除该节 点