【前端知识之Vue】diff算法流程

2023-11-01

前言

本系列主要整理前端面试中需要掌握的知识点。本节介绍diff算法流程以及相关例子。
如果想看源码推荐YK菌的【Vue源码】图解 diff算法 与 虚拟DOM-snabbdom-最小量更新原理解析-手写源码-updateChildren哦~
如果想一步一步跟着写源码推荐尚硅谷的【尚硅谷】Vue源码解析之虚拟DOM和diff算法哦~


一、diff算法是什么

  • diff算法是一种通过同层的树节点进行比较的高效算法;
  • 他的比较只会在同层级进行,不会跨层级比较;
  • 在diff比较的过程中,循环从两边向中间比较。
  • diff可以用在虚拟DOM更新时的新老虚拟节点比较的过程中。

二、虚拟节点之间进行比较的流程

在这里插入图片描述

  1. patch()函数是什么?patch函数是用于节点上树,更新DOM的函数,也就用将新旧节点进行比较的函数。
  2. 如果输入的新节点不是虚拟DOM , 那么就需要将DOM节点转换为虚拟DOM,这也印证了,diff算法是针对虚拟DOM的
  3. 比较新旧节点的sel和key是否相同,这里的sel指的是标签名,key就是节点的唯一标识。如果不同,那就直接删除+重新创建。如果相同那就继续往下判断。
if (oldVnode.key == newVnode.key && oldVnode.sel == newVnode.sel)
  1. 继续判断新旧是否就是一个对象,如果是,那就什么都不用
if (oldVnode === newVnode)
  1. 判断新节点是否有text属性(这里的因为是虚拟节点,就把text称为属性,实际上在DOM中,就是标签的文本内容)。如果有,再判断旧的虚拟节点是否有text,且两者是否相同,相同就不用做,不相同就需要修改节点的text。
  2. 如果没有,继续判断老的虚拟节点是否有子节点,如果老节点没有孩子,那么就把新节点的孩子添加到DOM中。
  3. 如果新老节点都有孩子,此时就要用diff算法来比较了!!!!

三、diff算法比较原则

diff算法包含四种命中查找:
①新前与旧前
②新后与旧后
③新后与旧前(此种发生后,涉及到移动节点,新后指向的节点,移动到旧后之后)
④新前与旧后(此种发生后,涉及到移动节点,新前指向的节点,移动到旧前之前)
命中一种就不再进行命中判断了,如果都没有命中,就需要用循环来寻找,移动到旧前之前。
结束查找的条件是:旧前<旧后 或者 新前<新后
在这里插入图片描述

1. 新前与旧前

  • 如果命中,则新前+1,旧前+1
    在这里插入图片描述
  • 如果没有命中,则看②新后与旧后能否命中,还不能就③新后与旧前能否命中,还不能就④新前与旧后能否命中。

2. 新后和旧后

  • 如果命中,则旧后-1 , 新后-1;
    在这里插入图片描述
  • 如果没有命中,则看③新后与旧前能否命中,还不能就④新前与旧后能否命中。

3. 旧前和新后

  • 如果命中,则将新后所指的节点移动到旧后之后,新后-1,旧前+1;
    在这里插入图片描述

  • 如果没有命中,则看④新前与旧后能否命中。

4. 旧后与新前

  • 如果命中,则将新前所指的节点移动到旧前之前,新前+1,旧后-1;
    在这里插入图片描述
  • 如果没有命中,则遍历旧节点的key。

5. 四种都没有命中,遍历旧节点的key

  • 下图的新节点中key=D的节点四种命中方式都不能命中,因此以新前指向的key=D为标准,遍历旧节点,直到找到了key=D;
  • 找到以后,将key=D的节点放在旧前指向之前,找到的节点设为undefined,新前指向+1
    在这里插入图片描述
    在这里插入图片描述
  • 没找的就是新节点,直接插入所有未处理旧节点之前

6. 循环结束

(1)如果新节点中还有剩余:就将新节点中剩余的都插入旧后之后或者旧前之前(旧后之后和旧前之前指的是同一个位置)。
在这里插入图片描述
(2)如果旧节点中还有剩余:就将旧前和旧后之间的(包括旧前和旧后)的节点删除。
在这里插入图片描述
在这里插入图片描述

四、diff算法举例

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【前端知识之Vue】diff算法流程 的相关文章

  • 在 JSP 中从 JavaScript/jQuery 调用后端 Java 方法

    我有一个 JSP 其中有一个select包含实体种类名称的列表 当我选择一个实体类型时 我需要填充另一个实体类型select包含所选实体类型的字段名称的列表 为此 我调用了一个 JavaScript 函数onchange event 在 J
  • PouchDB 和 CouchDB 的 Cookie 身份验证并未实际登录用户

    我有一个节点应用程序 它使用 CouchDB 作为数据库 在客户端使用 PouchDB 要登录 将向节点服务器发送请求 节点服务器使用 CouchDB 实例对用户的凭据进行身份验证 然后将 cookie 发送回客户端 问题是 重新启动浏览器
  • javascript应用于构造函数,抛出“格式错误的形式参数”

    感谢精彩的回复这个问题 https stackoverflow com questions 1959040 possible to send javascript varargs我了解如何使用可变参数调用 javascript 函数 现在我
  • 根据子节点数量动态调整 d3 树布局的大小

    从这个例子来看http mbostock github com d3 talk 20111018 tree html http mbostock github com d3 talk 20111018 tree html我已经建立了一个d3
  • 如何在jsdoc上添加和使用标签?

    我正在尝试向 jsdoc 添加自定义标签 我在插件目录中创建了一个文件 如下所示 方法 js exports defineTags function dictionary dictionary defineTag methodHttp mu
  • React Native + Redux 基本身份验证

    我正在寻找一种为我的反应本机应用程序创建基本身份验证的方法 我找不到任何反应本机应用程序的好例子 要登录 应用程序将电子邮件 密码 clientSecret 发送到我的服务器 如果OK 服务器返回accessToken refreshTok
  • 使用 JavaScript 解析时间

    这可能很简单 但我有点困惑如何做到这一点 我如何使用 JavaScript 仅解析以下内容中的时间ISO 8601 http en wikipedia org wiki ISO 8601日期字符串 2009 12 06T17 10 00 换
  • JavaScript 符号并不能阻止对象中的名称冲突

    我已经开始研究 JavaScript 中的符号 并开始在我的对象中使用它们来帮助解决名称冲突 但是在使用它们时我仍然可以覆盖属性吗 我很难理解 JavaScript 中符号的意义 它们被谈论了很多 人们说它们很聪明 因为它们不会导致对象中的
  • Svelte 路线给我 404

    我在 Svelte 中为我的应用程序创建了一个简单的路由器 如果我从导航栏访问链接 它就可以工作 如果我重新加载页面 它会给我 404 为什么
  • Vimeo 播放器 JS API 在 iOS 中无法运行

    我正在尝试使用 API 来播放视频 但只有在 iOS 中单击播放器中的播放按钮后它才有效 在桌面版和 Android 版 Chrome 中 它运行良好 http codepen io bdougherty pen JgDfm http co
  • 通过 Javascript 不断查询服务器 - 好主意吗?

    我有一个小型网站 大约有 5 到 10 名管理员 我已将其设置为监视每个管理员正在执行的操作 添加项目 删除项目等 我的管理面板中有一个列表 显示了集体管理部门之前执行的 10 项活动 今天 我决定每 30 秒进行一次自我更新 我的问题很简
  • 如何修改 Elasticsearch 文档的 _source 字段

    问题 有没有办法从文档的 source 中清除 html html 的剥离可以是周期性的 触发的 或者理想情况下是在索引时即时进行的 我将数据输入到elasticsearch中 并针对分析器进行索引 该分析器在索引之前剥离不需要的htmls
  • 没有 ssl 的 Web 加密 API

    我编写了一个用于安全消息传输的小网络应用程序 以了解有关加密的更多信息 并想向我的朋友展示它并让他们玩一下 所以我将它托管在我的小服务器上 并惊讶地发现 Web Crypto API 我竭尽全力开始工作 因为它的错误消息不是很具体 需要 S
  • 关闭模态后清除模态字段

    我有这个模式
  • jQuery 上下文菜单下拉菜单

    我正在使用这个 contextMenu 模板 http medialize github com jQuery contextMenu index html http medialize github com jQuery contextM
  • preg_match_all JS 等效吗?

    Javascript 中是否有与 PHP 的 preg match all 等效的函数 如果没有 将正则表达式的所有匹配项放入数组的最佳方法是什么 我愿意使用任何 JS 库来让它变得更容易 您可以使用match使用全局修饰符 gt gt g
  • 为什么onClick下一个视频函数,使用YouTube JavaScript Player API,质量下降到默认?

    我在 CodeIgniter 上遇到了这个问题 使用 next video API 函数 单击按钮时新视频的质量比以前的低 所以基本上第一个视频始终处于我建议的质量 而下一个始终处于默认质量 On my template我有这个div di
  • 删除已从另一个下拉菜单中选择的下拉值

    我在网上搜索了一段时间 但仍然找不到答案 我的网站上有三个下拉菜单 我使用它们来接受用户首选项 以便用户可以控制结果的输出 所以我想知道如果在其中一个下拉列表中选择了该值 是否可以从其他两个下拉列表中取出该值 例如 如果用户在第一个电影中选
  • 如何对数字进行排序? [复制]

    这个问题在这里已经有答案了 下面是代码 Is the sortNumber对数字进行排序的函数 a 和 b 是什么意思以及为什么存在 为什么sortNumber in n sort sortNumber 没有指定任何参数a and b Ja
  • 从 Bigcommerce 的浏览器内存中删除注入的分析库?

    我们如何删除这个脚本注入器系统并清除内存中的函数 简报 最近 Bigcommerce 的不法分子以 监控 为幌子创建了一个分析注入器 JS 该注入器被锁定在全局变量中 他们在未经任何 OP 同意的情况下将其推广到所有 50 000 家前台商

随机推荐