虚拟DOM的比较

patch

将虚拟DOM渲染成DOM,这就是patch的作用

在vue运行的时候会生成新旧两个虚拟DOM树,通过比较这两棵DOM树,我们就能针对性的修改真实DOM
事实上,我们大可以在每次比较两棵DOM树的时候删除现有的DOM结构,然后根据新的虚拟DOM来渲染最新的DOM,但这样做的结果就是性能开销过大,所以vue并没有采取这种方式,vue会比对新旧两个vnode之间有哪些不同,然后根据对比结果找出需要更新的节点进行更新
我们知道DOM的操作对比JavaScript的操作来说是十分消耗性能的,因此我们完全可以将大部分的DOM操作放在JavaScript中,通过各种算法来得到需要更新的DOM节点,也就是通过虚拟DOM的比对,也就是patching算法

在patch中针对虚拟DOM的比对主要分为三部分

新增节点

首次渲染

新增节点最明显的一个应用场景就是首次渲染,因为首次渲染没有oldVNode,只有newVNode,当只有newVNode时patch会直接根据newVNode来生成视图

首次渲染

节点不同

除了首次渲染,当两个对应位置的VNode完全不同时,patch也会新增节点,用这个新节点来生成DOM以替换原来的旧节点

创建节点

事实上,只有三种节点会被插入到视图中,分别是元素节点,注释节点,文本节点

我们可以通过调用不同的创建函数来得到不同的节点,如果一个节点有子节点的话那么将会递归创建,创建子节点时,子节点的父节点就是当前刚创建出来的这个节点,所以子节点被创建后,会被插入到当前节点的下面,当所有子节点都创建并插入完毕后如果父节点已经被渲染到视图中,那么将子节点插入进去之后,会将所有节点都渲染到视图中

插入节点

patch会根据不同的节点使用不同的插入方式:

  1. 元素节点
    patch会调用当前环境下的appendChild方法将指定节点插入到指定父元素之下
  2. 文本节点
    patch会调用当前环境下的createTextNode方法
  3. 注释节点
    patch会调用当前环境下的createComment方法

删除节点

删除节点的场景很简单,即如果当前节点不在newVNode中,patch就会将它删除,具体过程是将新创建的DOM节点插入到旧节点的旁边,然后再将旧节点删除,从而完成替换过程

更新节点

静态节点

在更新节点之前,patch会判断当前节点是否是静态节点,如果是的话就跳过更新步骤

静态节点即渲染到视图上后永远不会改变的节点

<p>我是静态节点,我不需要发生变化</p>

文本节点

如果新旧两个VNode的文本不一致,则以newVNode为准调用setTextContent方法

元素节点

如果newVNode有children的话则会判断oldVNode有无children,如果没有则正常创建DOM,有的话则会通过diff来进行更加细致的比对
如果newVNode无children的话这说明这个新创建的节点是一个空节点,则在DOM中有什么删什么就行,达到视图中是空标签的目的

diff

我们通过循环newChildren来对比两个子节点列表,每从newChildren中取出一个VNode我们就去oldChildren中对比,如果匹配成功,则做更新操作,如果没有找到就做新增操作,如果两个节点的位置不同,则移动节点

插入子节点

diff通过循环newChildren,每次循环拿出一个节点来和oldChildren对比,如果是新增节点那么就会插入到所有未处理节点的前面

插入子节点

需要注意的是,我们插入子节点时的位置是在oldChildren中所有未处理节点前对应的位置,而不是oldChildren中所有已处理节点后对应的位置

因为我们是使用虚拟节点进行对比,而不是真实DOM节点做对比,插入的位置也是由两个节点列表对比得到,如果插入到已处理节点之后的话会导致顺序混乱

插入子节点

删除节点

删除子节点,本质上是删除那些oldChildren中存在但newChildren中不存在的节点

即当newChildren中的所有节点都被循环了一遍后,如果oldChildren中还有剩余的没有被处理的节点,那么这些节点就是需要删除的节点

更新节点

最后我们来更新节点,如果一个新旧两个节点位置相同且是同一个节点,那么直接进行更新节点操作,如果位置不一致的话我们还需要移动节点

移动节点

我们以newChildren为基准,将真实DOM中为同一节点的节点通过insertBefore方法移动到指定位置,那么问题来了,我们如何确定将节点移动到哪里呢

我们比对节点列表时是通过for循环遍历newChildren的,那么就意味着当前所遍历到的项的前面所有节点都是处理好的,我们只需要将指定的节点(真实DOM)插入到所有未处理节点之前(相对于oldChildren)就行

移动子节点

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

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

相关文章

大数据-数据分析初步学习,待补充

参考视频&#xff1a;数据分析只需3小时从入门到进阶&#xff08;up亲身实践&#xff09;_哔哩哔哩_bilibili 数据指标&#xff1a; 对当前业务有参考价值的统计数据 分类&#xff1a;用户数据&#xff0c;业务数据&#xff0c;行为数据 用户数据 存量&#xff1a; DAU&#…

可信计算和数字水印技术

可信计算 可信计算可信计算基础概述可信计算关键技术要素可信性认证可信计算优劣 数字水印技术数字版权保护技术 可信计算 可信计算基础概述 可信计算&#xff08;Trusted Computing&#xff0c;TC&#xff09;&#xff1a;在计算和网络通信系统中广泛使用的、基于硬件安全模块…

Android Glide, first start based on loadThumbnail, Kotlin(二)

Android Glide, first start based on loadThumbnail, Kotlin&#xff08;二&#xff09; Android Glide, first start based on loadThumbnail, Kotlin&#xff08;一&#xff09;中有个小问题&#xff0c;通过loadThumbnail()采集到的缩略图真的就是整张图片的完整缩略图&…

C语言入门系列:数据类型之布尔类型

文章目录 1&#xff0c;以前&#xff0c;C语言没有布尔类型2&#xff0c;后来&#xff0c;C语言假装有了布尔类型3&#xff0c;再后来&#xff0c;C语言的非标布尔类型 1&#xff0c;以前&#xff0c;C语言没有布尔类型 其实&#xff0c;C 语言没有真正的布尔类型&#xff0c;…

STM32通过I2C软件读写MPU6050

文章目录​​​​​​​ 1. MPU6050 1.1 运动学概念 1.2 工作原理 2. 参数 2.1 量程选择 2.2 I2C从机地址配置 3. 硬件电路 4. 框架图 5. 软件和硬件波形对比 6. 软件I2C读写MPU6050 6.1 程序整体构架 6.2 一些需要注意的点&#xff1a; 6.3 MPU6050初始化配置 6…

支持 MKV、MP4、AVI、MPG 等格式视频转码器

一、简介 1、一款开源的视频转码器&#xff0c;适用于 Linux、Mac 和 Windows。它是一个免费的工具&#xff0c;由志愿者们开发&#xff0c;可以将几乎所有格式的视频转换为现代、广泛支持的编码格式。你可以在官网上下载该应用或源代码。该软件支持 MKV、MP4、AVI、MPG 等格式…

如何计算文档会消耗的Token数量?

在AI的世界里&#xff0c;"token"就像是把我们说的话或写的文字拆分成的小块块&#xff0c;每块可以是一个词、一个短语、一个标点&#xff0c;甚至一个字母。不同的AI系统可能有不同的拆分方法。 阿里云的灵积平台有个工具&#xff0c;叫做Token计算器。这个工具就…

经常混淆的ADC输入类型!

大家好,这里是大话硬件。 这篇文章我们来聊聊ADC的输入类型。 ADC的输入类型根据ADI的官网,分为了3种类型,单端,差分,伪差分。如下图快速选型的界面所示。 同时,TI的官网对ADC的输入类型划分也是同样的3种类型。 可见,两个器件厂家对ADC的输入类型都是这样定义的。 …

springMVC的bug

写SpringMVC时&#xff0c;配置视图解析器路径中少写了个“/”导致url拼接错误&#xff0c;无法返回视图

支持向量机 (SVM) 算法详解

支持向量机 (SVM) 算法详解 支持向量机&#xff08;Support Vector Machine, SVM&#xff09;是一种监督学习模型&#xff0c;广泛应用于分类和回归分析。SVM 特别适合高维数据&#xff0c;并且在处理复杂非线性数据时表现出色。本文将详细讲解 SVM 的原理、数学公式、应用场景…

项目中选择Entity Framework Core还是Dapper?

我是将 Dapper 还是 Entity framework core 用于下一个 .NET 项目&#xff1f;当你必须做出这个决定时&#xff0c;总是令人困惑&#xff0c;为了项目的成功&#xff0c;你需要做出正确的决定。让我来帮你... 介绍 使用 .NET 开发的应用程序可以根据其使用的对象关系映射器 &…

Java | Leetcode Java题解之第168题Excel表列名称

题目&#xff1a; 题解&#xff1a; class Solution {public String convertToTitle(int columnNumber) {StringBuffer sb new StringBuffer();while (columnNumber ! 0) {columnNumber--;sb.append((char)(columnNumber % 26 A));columnNumber / 26;}return sb.reverse().t…

【APP移动端性能测试】第一节.APP应用架构、环境和敏捷开发模型介绍

文章目录 前言一、APP应用架构二、APP项目环境 2.1 后端项目环境 2.2 前端项目环境三、Scrum敏捷开发模型 3.1 Scrum敏捷模型基础介绍 3.2 Scrum敏捷开发开发流程总结 前言 一、APP应用架构 &#xff08;1&#xff09;APP应用架构 &#xff08;2&#xff0…

springboot应用cpu飙升的原因排除

1、通过top或者jps命令查到是那个java进程&#xff0c; top可以看全局那个进程耗cpu&#xff0c;而jps则默认是java最耗cpu的&#xff0c;比如找到进程是196 1.1 top (推荐)或者jps命令均可 2、根据第一步获取的进程号&#xff0c;查询进程里那个线程最占用cpu&#xff0c;发…

js 用正则表达式 匹配自定义字符之间的字符串数据,如:( )、[ ]、{ }、< >、【】等括号之间的字符串数据

要使用正则表达式匹配尖括号()之间的数据&#xff0c;可以使用以下代码示例&#xff1a; 在JavaScript中&#xff0c;你可以使用正则表达式来匹配括号()之间的数据。以下是一个简单的例子&#xff0c;它展示了如何使用正则表达式来获取两对括号之间的文本。 // 示例字符串 con…

LENOVO联想 小新 16 IAH8 2023款(83BG)笔记本原厂Windows11系统,恢复出厂开箱状态预装OEM系统镜像安装包下载

适用型号&#xff1a;小新 16 IAH8【83BG】 链接&#xff1a;https://pan.baidu.com/s/18VbGbBXtQEW5P8wLIyJtAQ?pwddv1s 提取码&#xff1a;dv1s 联想原装Win11系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、系统属性专属LOGO标志、Office办公软件、联想电脑管家…

董宇辉的人生关键词:年轻人的成长指南

在当今这个信息爆炸、竞争激烈的社会中&#xff0c;年轻人面临着前所未有的挑战与机遇。如何从纷繁复杂的世界中找到属于自己的道路&#xff1f;近日&#xff0c;知名人生导师董宇辉为年轻人提出了几个人生关键词&#xff0c;这些词汇不仅凝聚了他多年的人生感悟&#xff0c;更…

【STM32-ST-Link】

STM32-ST-Link ■ ST-Link简介■ ST-Link驱动的安装。■ ST-Link编程软件(MDK)配置。■ ST-Link固件升级方法 ■ ST-Link简介 由于德产 J-LINK 价格非常昂贵&#xff0c; 而国产 J-LINK 因为版权问题将在万能的淘宝销声匿迹。 所以我们有必要给大家介绍 JTAG/SWD 调试工具中另…

如何做好技术管理与技术规划?

一、背景 做好技术管理不仅要求紧跟行业前沿动态&#xff0c;同时也需把握好产品开发的阶段性分期&#xff0c;确保技术成果转化和产品落地的顺畅进行。技术管理的成功与否&#xff0c;在很大程度上取决于能否精准捕捉市场需求&#xff0c;据此调整任务优先级。面对瞬息万变的…

Day10—Spark SQL基础

Spark SQL介绍 ​ Spark SQL是一个用于结构化数据处理的Spark组件。所谓结构化数据&#xff0c;是指具有Schema信息的数据&#xff0c;例如JSON、Parquet、Avro、CSV格式的数据。与基础的Spark RDD API不同&#xff0c;Spark SQL提供了对结构化数据的查询和计算接口。 Spark …