vue2-diff算法

1、diff算法是什么?
diff算法是一种通过同层的树节点进行比较的高效算法。
其有两个特点:
比较只会在同层级进行,不会跨层级进行。
在diff比较的过程中,循环从两边向中间比较。
diff算法在很多场景中都有应用,在vue中,作用于虚拟Dom渲染成真实dom的新旧Vnode节点比较

2、比较方式
diff整体策略为:深度优先,同层比较
1)比较只会在同层级进行,不会跨层级比较
在这里插入图片描述

2)比较的过程中,循环从两边向中间收拢。
在这里插入图片描述
下面举一个vue通过diff算法更新的例子。
新旧vnode节点如下图所示:
在这里插入图片描述
第一次循环后,发现旧节点D与新节点D相同,直接复用旧节点D作为diff后的第一个真实节点,同时旧节点endIndex移动到C,新节点的startIndex移动到C。在这里插入图片描述
第二次循环后,同样是旧节点的末尾和新节点的开头相同(节点C),同理,diff后创建了C的真实节点插入到第一次创建的D节点后面,同时旧节点的endIndex移动到了B,新节点的startIndex移动到了E。
在这里插入图片描述
第三次循环中,发现E没有找到,这时候只能直接创建新的真实节点E,插入到第二次创建的C节点之后。同时新节点的startIndex移动到了A,旧节点的startIndex和endIndex都保持不动。
在这里插入图片描述
第四次循环中,发现了新旧节点的开头相同(都是A),于是diff后创建了A的真实节点,插入到前一次创建的E节点后面。同时旧节点的startIndex移动到了B,新节点的startIndex移动到了B。
在这里插入图片描述
第五次循环中,与第四次循环一样,因此diff后创建了B真实节点,插入到前一次创建的A节点后面。同时旧节点的startIndex移动到了C,新节点的startIndex移动到了F。
在这里插入图片描述
新节点的startIndex已经大于endIndex了,需要创建newStartIdx和newEndIdx之间的所有节点,也就是节点F,直接创建节点F对应的真实节点放到B节点后面。
在这里插入图片描述
3、原理分析
当数据发生改变时,set方法会调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁,更新相应的视图。
源码位置:/src/core/vdom/patch.js
在这里插入图片描述
在这里插入图片描述
patch函数前两个参数位为oldVnode和Vnode,分别代表新的节点和之前旧的节点,主要是做了4个判断。
没有新节点,直接触发旧节点的destory钩子
没有旧节点,说明是页面刚开始初始化的时候,此时根本不需要比较,直接全是新建,所以调用createElm
旧节点和新节点自身一样,通过saveVnode判断节点是否一样,一样时直接调用patchVndoe去处理这两个节点
旧节点和新节点自身不一样,当两个节点不一样时,直接创建新节点,删除旧节点。

下面分析下patchVnode部分:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
patchVnode主要做了以下几个判断:
新节点是否为文本节点,如果是,则直接更新dom的文本内容为新节点的文本内容
新节点和旧节点如果都有子节点,则处理比较更新子节点
只有新节点有子节点,旧节点没有,那就不用比较了,所有节点都是全新的,所以直接全部新建就好了,新建是指创建出所有新的DOM,并且添加进父节点
只有旧节点有子节点,新节点没有,说明更新后的页面,旧节点全部都不见了,那么要做的就是把所有旧节点删除,也就是直接把DOM删除

子节点不完全一致,则调用updateChildren
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
while主要是处理了以下5个场景:
当新老Vnode节点的start相同时,直接patchVndoe,同时新老Vnode节点的开始所以都加1
当新老Vnode节点的end相同时,同样直接patchVnode,同时新老Vnode节点的结束所以都减1
当老节点Vndoe的start和新Vnode节点的end相同时,这时候patchVndoe后,还需要将当前真实dom节点移动到oldEndVnode的后面,同时老Vnode节点开始索引加1,新Vnode节点的结束所以减1
当老Vnode节点的end和新Vnode节点的start相同时,这时候patchVnode后,还需要将当前真实dom节点移动到oldStartVnode的前面,同时老Vnode节点结束索引减1,新Vnode节点的开始索引加1
如果都不满足上述4种情况,那说明没有相同的节点可以复用,则会分为以下两种情况。
从旧的Vnode为key的值,对应index序列为value值的哈希表中找到与newStartVnode一致key的旧的Vnode节点,再进行patchVndoe,同时将这个真实dom移动到oldStartVnode对应的真实dom的前面
调用createElm创建一个新的Dom节点放到当前newStartIdx的位置。

4、小结
当数据发生改变时,订阅者watcher就会调用patch给真实的dom打补丁
通过isSameVNode进行判断,相同则调用patchVnode方法

patchVnode做了以下操作:
找到对应的真实dom,称为el
如果都有文本节点且不相等,将el文本节点设置为Vnode的文本节点
如果oldVnode有子节点而Vnode没有,则删除el子节点
如果oldVnode没有子节点而Vnode有,则将Vnode的子节点真实化后添加到el
如果两者都有子节点,则执行updateChildren函数比较子节点

updateChildren主要进行以下操作:
设置新旧Vnode的头尾指针
新旧头尾指针进行比较,循环向中间靠拢,根据情况调用patchVnode进行patch重复流程,调用createElem创建一个新节点,从哈希表寻找key一致的Vnode节点再分情况操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/78351.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac电脑访问windows共享文件夹连接不上(设置445端口)

前提:首先需要保证mac和windows都在同一局域网内,如果不在肯定是连不上的,就不用往下看了。 事情是这样的,公司入职发了mac电脑,但是我是window重度用户,在折腾mac的过程中,有许多文件需要从wi…

【Jenkins】Jenkins 安装

Jenkins 安装 文章目录 Jenkins 安装一、安装JDK二、安装jenkins三、访问 Jenkins 初始化页面 Jenkins官网地址:https://www.jenkins.io/zh/download/ JDK下载地址:https://www.oracle.com/java/technologies/downloads/ 清华源下载RPM包地址&#xff…

vim、awk、tail、grep的使用

vim命令 $定位到光标所在行的行末^定位到光标所在行的行首gg定位到文件的首行G定位到文件的末行dd删除光标所在行ndd删除n行(从光标所在行开始)D删除光标所在行,使之变为空白行x删除光标所在位置字符nx删除n个字符,从光标开始向后…

使用Python将Word文档转换为PDF的方法

摘要: 文介绍了如何使用Python编程语言将Word文档转换为PDF格式的方法。我们将使用python-docx和pywin32库来实现这个功能,这些库提供了与Microsoft Word应用程序的交互能力。 正文: 在现实生活和工作中,我们可能会遇到将Word文…

召唤神龙打造自己的ChatGPT

在之前的两篇文章中,我介绍了GPT 1和2的模型,并分别用Tensorflow和Pytorch来实现了模型的训练。具体可以见以下文章链接: 1. 基于Tensorflow来重现GPT v1模型_gzroy的博客-CSDN博客 2. 花费7元训练自己的GPT 2模型_gzroy的博客-CSDN博客 有…

揭秘女程序员找男友的首选职业,你猜是哪个?

大家好,这里是程序员晚枫。 大家有没有发现:身边单身的男程序员很多,而单身的女程序员更多? 今天我们就来一起讨论一下,女程序员适合什么职业的男生?01 推荐 女程序员适合什么职业的男生,这…

一篇文章教会你一个优秀的程序员如何维护好自己的电脑

程序员如何维护好自己的电脑 1. 程序员的电脑种类都有哪些2. 硬件如何维护2.1 开关机问题2.2 Windows更新问题2.3 笔记本充电和电池问题2.4 笔记本清灰问题 3. 系统及软件维护3.1 杀毒软件和垃圾清理问题3.2 磁盘分盘问题3.3 浏览器和搜索引擎的选择3.4 系统备份和PE盘的使用 总…

ELK、ELFK日志分析系统

菜单一、ELK简介1.1 ELK组件说明1.1.1 ElasticSearch1.1.2 Kiabana1.1.3 Logstash 1.2 可以添加的其它组件1.2.1 Filebeat1.2.2 缓存/消息队列(redis、kafka、RabbitMQ等)1.2.3 Fluentd 1.3 为什么要用ELK1.4 完整日志系统的基本特征1.5 ELK 的工作原理 …

2023年华数杯数学建模A题思路代码分析 - 隔热材料的结构优化控制研究

# 1 赛题 A 题 隔热材料的结构优化控制研究 新型隔热材料 A 具有优良的隔热特性,在航天、军工、石化、建筑、交通等 高科技领域中有着广泛的应用。 目前,由单根隔热材料 A 纤维编织成的织物,其热导率可以直接测出;但是 单根隔热…

Selenium自动化测试总结

一、Selenium自动化测试(基于python) 1、Selenium简介: 1.1 Selenium是一款主要用于Web应用程序自动化测试的工具集合。Selenium测试直接运行在浏览器中,本质是通过驱动浏览器,模拟浏览器的操作,比如跳转、…

Springboot+Easyexcel将数据写入模板文件并导出Excel

SpringbootEasyexcel将数据写入模板文件并导出Excel 一、导入依赖二、根据excel表头创建对应的实体类Pojo三、Controller类接收请求四、Service层获取待写入数据五、效果展示六、总结 一、导入依赖 <!--操作excel工具包--> <dependency><groupId>com.alibab…

Spring 事务详解(注解方式)

目 录 序言 1、编程式事务 2、配置声明式事务 2.1 基于TransactionProxyFactoryBean的方式&#xff08;不常用&#xff0c;因为要为每一个类配置TransactionProxyFactoryBean&#xff09; 2.2 基于AspectJ的XML方式&#xff08;常用&#xff0c;可配置在某些类下的所有子…

Kubernetes 整体架构介绍

架构图 Kubernetes 主要由以下几个核心组件组成&#xff1a; etcd 保存了整个集群的状态&#xff1b;kube-apiserver 提供了资源操作的唯一入口&#xff0c;并提供认证、授权、访问控制、API 注册和发现等机制&#xff1b;kube-controller-manager 负责维护集群的状态&#xf…

在线推算给定日期指定天数前(后)的日期

在线推算给定日期指定天数前(后)的日期

点击编辑变完成

<template><div><button click"dialogshowtrue">添加部门</button><div>部门列表</div><el-table ref"multipleTable" :data"form" tooltip-effect"dark" style"width: 100%">&l…

【雕爷学编程】MicroPython动手做(27)——物联网之掌控板小程序

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

单例模式(C++)

定义 保证一个类仅有一个实例&#xff0c;并提供一个该实例的全局访问点。 应用场景 在软件系统中&#xff0c;经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例&#xff0c;才能确保它们的逻辑正确性、以及良好的效率。如何绕过常规的构造器&#xff0c;提供一种…

怎么学习CSS相关技术知识? - 易智编译EaseEditing

学习CSS技术是前端开发中的重要一环&#xff0c;它用于控制网页的样式和布局&#xff0c;使网页更加美观和易于使用。以下是学习CSS技术的几个方面&#xff1a; 基本语法和选择器&#xff1a; 了解CSS的基本语法&#xff0c;学习如何使用选择器来选择HTML元素并应用样式。 样…

Linux 下设置开机自启动的方法

文章目录 事先准备对于普通的 Linux对于 RedHat Enterprise Linux 9 笔者的运行环境&#xff1a; 设置成功过的 Linux&#xff1a; RedHat Enterprise Linux 9 x86_64 CentOS 8 x86_64 事先准备 进行这个教程之前&#xff0c;必须要先安装好一个 Linux 操作系统。这个 Linux…

【C语言进阶】指针的高级应用(中)

本专栏介绍&#xff1a;免费专栏&#xff0c;并且会持续更新C语言知识&#xff0c;欢迎各位订阅关注。 关注我&#xff0c;带你了解更多关于机器人、嵌入式、人工智能等方面的优质文章&#xff0c;坚持更新&#xff01; 大家的支持才是更新的最强动力&#xff01; 文章目录 一、…