patch函数被调用到diff之前的工作

这篇博客探讨了在更新DOM时如何进行精细化比较,只对同一虚拟节点进行同层比较,避免跨层。文章介绍了如何将真实DOM转换为虚拟DOM,并在新旧节点不同时,决定是进行精细化比较还是暴力插入新节点。在精细化比较中,处理了文本节点的特殊性,以及在有嵌套结构的节点间的diff算法。此外,还提到了如何递归处理嵌套的虚拟DOM节点,确保正确构建DOM树。
摘要由CSDN通过智能技术生成

首先,我们要知道什么情况下才会进行精细化比较:

  1. 只有是同一个虚拟节点,才进行精细化比较;
  2. 只进行同层比较,不会进行跨层比较。

在这里插入图片描述

上树的前提是此节点必须是虚拟dom节点,因此在上树前要进行虚拟dom判断,如果是真实dom节点,那就先将其包装为虚拟节点:

if(oldVnode.sel == '' || oldVnode.sel == underfined){
    oldVnode = vnode(oldVnode.tagName.toLowerCase(), {}, [], underfined, oldVnode);
}

上树的另一个条件是两个节点是同一个节点,如果是同一个节点,进行diff精细化比较,如果不是同一个节点,那就暴力插入新的,删除旧的节点:

if(oldVnode.key == newVnode.key && oldVnode.sel == newVnode.sel){
	// 是同一个节点,进行diff精细化比较
}else{
    // 暴力插入新的,删除旧的节点
}
暴力插入新的,删除旧的节点

假设我们现在要做的操作时暴力插入新的节点,那我们此时就需要一个新的函数createElement专门做上树的操作,这个函数接收要插入的虚拟节点vnode,返回真实dom节点,patch函数将其返回值插入到旧节点上,完成上树。

这里需要注意的是:在patch函数执行过程中,免不了出现嵌套的虚拟dom结构,那么如何利用递归实现嵌套的虚拟dom节点真实dom化就成了本算法中的重点。

在createElement函数中将传入的虚拟dom节点分为五嵌套结构的和有嵌套结构的,无嵌套结构的会直接创建出真实dom节点并加入文字等内容;有嵌套结构的则会循环遍历其中的children属性,并将其每一个children调用createElement函数实现递归,最后appendChild收集起来返回给patch函数。

同一个节点的精细化比较

在这里插入图片描述

在进行精细化比较之前,我们还要处理几种特殊情况。

当前节点进来后,我们首先要判断这是不是和老的节点一模一样,也就是在内存中就是相等的(判断 的时候用===),如果是相等的,那就不需要往下比较了,该节点并没有变化;

如果这里新老节点不相同,那就要进行比较了,但是这里我们需要判断一下新节点是否存在text属性,如果存在那就代表这个新的节点内部只有文字,我们只需要改掉老节点内部的text属性;

当新老节点不同并且新节点内部不存在text属性(新节点有Children),那我们就要知道老节点是否有text属性(老节点是否有Children),如果有text,那就代表这个节点已经是最底部的节点了,我们只需要把新节点放在这即可;

如果新老节点都存在Children,那就是最麻烦的情况(五角星),此时就要进行diff精细化比较了。

参考尚硅谷邵老师教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值