虚拟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 等格式…

OpenCV--形态学

形态学 形态学图像全局二值化自适应阈值腐蚀操作膨胀开运算闭运算形态学梯度顶帽操作黑帽操作 形态学 从图像中提取对表达和描绘区域形状有意义的图像分量 图像全局二值化 import cv2 import numpy as np """ 图像全局二值化--0与255 二值化的主要目的是通过…

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

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

经常混淆的ADC输入类型!

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

简说贪心算法

贪心算法&#xff08;Greedy Algorithm&#xff09;是一类在每一步选择中都做出当前最优解&#xff0c;以期望通过一系列局部最优选择达到全局最优解的算法。贪心算法的核心思想是通过一次次的局部优化来构建全局解。尽管这种方法不总是能找到全局最优解&#xff0c;但在许多情…

springMVC的bug

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

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

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

三目运算符中间的表达式可以省略吗(a?:c)?

熟悉C语言的童靴对三目运算符都非常熟悉&#xff0c;a? b : c; 如果a为true&#xff0c;则整个运算符的值为b,否则为c;那么问题来了&#xff0c;三目运算符中间的表达式可以省略吗?即a? : c; 1、linux内核中出现的省略情况 本人在阅读内核代码是发现了下面的代码: preferr…

centos7 低版本docker 升级为高版本

删除 docker yum -y remove docker*安装 yum 管理工具 yum install -y yum-utils添加国内镜像 manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo查看可用软件版本yum list docker-ce --showduplicates|sort -r安装 yum -y install docke…

机器学习实验--- 金融数据基础与计算在线实验闯关

第1关&#xff1a;申万家用电器行业股票代码获取 任务描述 本关任务&#xff1a;根据右边测试平台的提示&#xff0c;补充代码。 # -*- coding: utf-8 -*- #1.读取“申万行业分类.xlsx”表&#xff0c;字段如下所示&#xff1a; # 行业名称 股票代码 股票名称 # 获得“…

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

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

「前端+鸿蒙」鸿蒙应用开发-在线教育测验案例

在鸿蒙应用开发中,状态管理是确保应用能够响应用户交互并保持数据一致性的关键。以下是一个状态管理的真实案例,包括功能简介、布局和样式、状态定义、业务逻辑、UI交互等。 案例 - 在线教育测验应用 功能简介 用户可以进行选择题测验。应用提供自动评分和统计信息。用户可以…

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;发…