个人理解Vue的diff算法

vue的diff算法是一种用来比较新旧虚拟DOM节点的高效算法

它的优点是:
最小化DOM操作的数量,提高性能和效率
可以处理大型虚拟DOM树,提高渲染速度
可以处理复杂的数据结构,如嵌套列表和嵌套对象
可以利用key属性来优化列表渲染,避免不必要的节点移动
总结起来主要是效率的提升,可以对真实DOM进行局部更新,而不需要重新渲染整个DOM树。

它有以下特点:
1.它只在同层级进行比较,不会跨层级比较。
(以下是找了较为形象的网图)
在这里插入图片描述
2.它在比较过程中,会从两边向中间进行循环比较。
在这里插入图片描述

3.它会优先找到相同且不需要移动的节点,然后找到相同但需要移动的节点,最后才会创建或删除节点
1)vue是通过tag和key来判断两个节点是否相同的 。具体来说,就是比较两个节点的tag属性和key属性是否都相等,如果都相等,就认为是相同的节点,否则就是不同的节点 。
2)tag和key都是vue的虚拟DOM节点的属性,它们用来标识和区分不同的节点。
tag是节点的标签名,比如div的tag就是div,p的tag就是p等等。tag可以用来判断两个节点是否是同一种类型的元素。
key是节点的唯一标识,它可以是数字或字符串。key可以用来判断两个节点是否是同一个元素
3)用tag和key来判断的原因是为了提高虚拟DOM的更新效率,减少不必要的DOM操作,提高性能。
用tag来判断可以快速判断两个节点是否是同一种类型的元素,如果不同,就直接删除重建,不再深度比较。
用key来判断可以快速判断两个节点是否是同一个元素,如果相同,就可以复用或移动,不需要重新创建。
如果不用tag和key来判断,vue会使用一种就地复用的策略,尽可能地修改或复用相同类型的元素,这样可能会导致一些隐藏的bug或者多余的DOM操作

用文字说明第三点的流程如下
假设有两个虚拟DOM节点数组,oldChildren和newChildren,它们的长度都是n,我们要比较它们的差异,并更新DOM。

首先,我们定义四个指针,oldStartIdx,oldEndIdx,newStartIdx和newEndIdx,分别指向oldChildren和newChildren的头部和尾部。

然后,我们开始一个循环,直到任意一个数组遍历完毕为止。

在每次循环中,我们按照以下的顺序进行比较:

如果oldChildren[oldStartIdx]和newChildren[newStartIdx]是相同节点(即tag和key都相等),则更新它们,并把两个指针都向右移动一位。
如果oldChildren[oldEndIdx]和newChildren[newEndIdx]是相同节点,则更新它们,并把两个指针都向左移动一位。
如果oldChildren[oldStartIdx]和newChildren[newEndIdx]是相同节点,则更新它们,并把这个节点移动到右边界的下一个位置,然后把两个指针分别向右和向左移动一位。
如果oldChildren[oldEndIdx]和newChildren[newStartIdx]是相同节点,则更新它们,并把这个节点移动到左边界的位置,然后把两个指针分别向左和向右移动一位。
如果以上四种情况都不满足,说明没有找到相同的节点。这时候我们就需要创建一个新的节点,并插入到合适的位置。具体的步骤如下:
我们创建一个patch对象,用来存储oldChildren中每个节点的key和索引的映射关系。
我们根据newChildren[newStartIdx]的key,在patch中查找是否有对应的索引值。
如果没有找到,说明这个节点是新创建的,我们就创建一个新的DOM元素,并插入到左边界的位置。
如果找到了索引值,说明这个节点在旧数组中存在,我们就取出这个节点,并更新它,并把这个节点移动到左边界的位置。
无论是否找到索引值,我们都把newStartIdx向右移动一位。
当循环结束时,可能会有两种情况:

如果oldStartIdx > oldEndIdx,说明旧数组先遍历完毕,而新数组还有剩余的节点。这时候我们就把剩余的新节点都插入到右边界的下一个位置。
如果newStartIdx > newEndIdx,说明新数组先遍历完毕,而旧数组还有剩余的节点。这时候我们就把剩余的旧节点都删除掉。
这样,我们就完成了两个虚拟DOM节点数组的比较和更新。

用伪代码模拟一下流程如下:
假设有两个虚拟DOM树,在这里插入图片描述
那么diff算法的模拟过程为:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值