• Vue2源码-diff算法详解


    Vue2中的diff算法,在面试中经常会被问到,这篇文章就来记录一下我学习时的一些理解。

    vue中是先将新旧节点转为虚拟节点后再进行比对,并且采用的是同层对比的方式,也就是只比较相同层级的节点,只有当它们两都相同时才会去对比它们下面的子节点,并进行核心的diff算法。

    首先,我们需要一个函数来对比新旧vnode是否相同,判断的办法是通过判断它们的 tag 和 key 是否相同来决定的。
    在这里插入图片描述
    然后就可以开始比对两个vnode了,如果不是同一个vnode,那么就用新的vnode将旧的vnode替换掉,如果是文本的话,需要比对新旧两文本是否相同,如果不同则将新文本更新进去,这里通过判断旧的vnode有没有tag这个属性来判断是否为文本。
    然后就来到了 updateProperties 这个函数这里,这个函数下面会说明,这里先不管,来到这里就说明两个vnode都是元素并且标签也一样,通过 updateProperties 这个函数去更新里面的各种属性,比如样式啊,传值啊等等。
    在这里插入图片描述

    updateProperties 函数具体实现,比较前后属性是否一致 老的有新的没有,将老的删除掉,如果新的有 老的 也有,以新的为准,如果新的有老的没有,直接替换成新的
    在这里插入图片描述
    到了这一步后,就要对其子节点进行对比了,首先就是两种简单情况,下面代码都有注释就不多说了,这里主要说一下双方都儿子的这种情况,也就是diff真正用上的地方。
    在这里插入图片描述


    vue中比较新旧儿子节点时,使用的双指针的方案,也就是在新旧vnode的头部和尾部都用一个标识去记住它们,可以用图来表示一下,如下图,黑色的为头指针,紫色的为尾指针。
    在这里插入图片描述
    代码实现如下,拿到四个指针的索引以及它们对应的虚拟节点。
    在这里插入图片描述


    接着创建一个while来循环遍历节点,只有当新旧vnode 的头尾指针同时重合才会结束这一次的遍历。
    在这里插入图片描述


    首先第一种情况是从头指针开始比对,这里用我们刚刚写的patchVnode函数去比对两个vnode的标签、属性, 当比对成功,说明这个节点可以复用后,将两个头指针向下一个节点继续比对。
    在这里插入图片描述
    在这里插入图片描述


    当头指针比对失败时,这个时候就要比对尾指针的vnode了,比对成功则将两个尾指针向前一个节点移动,继续比对。
    在这里插入图片描述
    在这里插入图片描述


    当尾指针也匹配失败的时候,就需要通过旧节点头部与新节点尾部比对,旧节点尾部与新节点头部比对的方式来进行,比对到相同节点后,通过 insertBefore 这个api 来操作节点,inseetBefore是具备移动性的,移动走了,原来的就不存在了。
    旧节点头部与新节点尾部比对时,比对成功后将节点插入到旧节点尾部的下一个节点中。
    旧节点尾部与新节点头部比对时,比对成功后将节点插入到旧节点头部的上一个节点中。
    在这里插入图片描述
    在这里插入图片描述

    当以上策略都无法比对节点时,这种情况就是乱序的比对方案了,一般出现在对列表进行操作。在vue中是建议对列表的元素都给一个独一无二的 key 来进行标识。有了 key 以后就可以去创建一旧节点的映射表,让新节点逐一去映射表中搜索,如果找不到则说明需要新增一个节点并将其插入到 旧头部节点之前,如果找到则说明需要进行复用并且需要移动
    在这里插入图片描述

    创建映射表如下图。
    在这里插入图片描述
    在映射表中找不到节点的情况,直接将这个新节点创建出来,插入就行了。
    在这里插入图片描述

    能在映射表中找到,那就将这个节点进行复用并且将他移动到旧的头部节点前,这里需要注意一下,将这个节点移出去以后会导致他本身的位置空缺,然后后面的节点就会往前补位,导致索引错乱的问题,所以为了不让这个问题出现,就需要在原来节点的地方给他赋值一个 null 来填补。
    在这里插入图片描述

    最后移除老的中新的不需要的元素。
    在这里插入图片描述

    还有一种情况就是新的比老得多,这个时候我可以取一下当前的下一个元素,如果有我就做插入,如果没有 就做追加。
    在这里插入图片描述

  • 相关阅读:
    RAID的基本工作模式
    SSD202 Linux开发日志记录
    ElasticSerach+MongoDB:实现文章检索历史功能
    Jmeter参数化方式
    如何避免Facebook账号被封,要注意哪些地方?
    软件工程毕业设计课题(28)基于JAVA毕业设计JAVA教室实验室预约系统毕设作品项目
    C++多态总结
    2021年3月-第02阶段-前端基础-Flex 伸缩布局-移动WEB开发_flex布局
    Bio-MOF-100 金属有机骨架材料
    logback--基础--02--配置--configuration
  • 原文地址:https://blog.csdn.net/weixin_46831501/article/details/126031613