Vue教程十二——虚拟DOM

【vue3源码】十二、认识虚拟DOM 虚拟DOM(也可以称为vnode)描述了一个真实的DOM结构,它和真实DOM一样都是由很多节点组成的一个树形结构。 阅读详情

虚拟DOM

在此章节,讲解一下关于Vue虚拟DOM的知识点。
那什么是虚拟DOM呢,这里了解一下页面渲染的过程。

页面渲染

当我们请求页面时,HTTP请求返回就会返回页面HTML数据:

1、首先会将HTML信息构建成DOM节点树
2、之后将CSS样式构建成CSSOM树
3、之后将上面的两棵树结合形成一个render树
4、Layout,根据render树计算出每一个渲染对象的位置和尺寸,将其安置在浏览器窗口的正确位置
5、最后根据排版后的结构进行页面的绘制Painting

注意,这是一个极其复杂耗时的过程,假如我们执行操作,一次改一点,一次改一点,那么就需要一遍又一遍的删除原来的DOM,然后执行上面的页面渲染重新构建DOM,页面就会卡死,所以Vue的虚拟DOM就是帮助解决这个问题的。

虚拟DOM

Vue的虚拟DOM就是解决上面页面反复加载问题的,Vue会构建了和真实DOM结构相似的一个虚拟的DOM,注意:真实DOM是HTML构建的,但是,虚拟DOM只是构建一个对象而已。

当页面发生变化了,虚拟DOM会帮助生成一个新的节点,然后比较一下新旧两个节点(注意,这两个所谓的节点,都只是虚拟DOM弄的对象而已),如果新旧节点不一样,再把新节点构建成真实的DOM节点放到真实DOM上,这一顿操作下来,就相当于打补丁,但是真的缓解了很多,就不需要直接摧毁原来的DOM重建。

更新过程

1、创建虚拟DOM的JS对象
2、Diff算法进行节点的新旧比较
3、patch打补丁,更新到真实DOM上

首先我们先把这个虚拟更新的函数写出来,不需要全看懂,下面会介绍:

function patch (oldVnode, vnode) {
    // 当oldVnode不存在时
    if (!oldVnode)) {
        // 创建新的节点
        createElm(vnode)
    } else {
    	// 判断新老节点是否是同一节点
    	// 如果是同一节点,执行patchVnode进行子节点比较;
		// 如果不是同一节点,新节点直接替换老节点;
        if (sameVnode(oldVnode, vnode)) {
        	// 对oldVnode和vnode进行diff,并对oldVnode打patch
        	patchVnode(oldVnode, vnode)  // diff在这里
  		}else {
  			createElem(vnode) // 根据Vnode生成新元素, 新节点直接替换老节点
  		}
    }
}

1、创建虚拟DOM

所谓创建虚拟DOM,便是将真实的DOM节点以JS对象的形式表达出来,举个🌰:

<div id="app" class="page-box">
   <p>this is demo</p>
{
    tag: 'div'
    data: {
        id: 'app',
        class: 'page-box'
    },
    children: [
        {
            tag: 'p',
            text: 'this is demo'
        }
    ]
}

2、Diff算法

创建完虚拟DOM后,当数据发生更新,就需要判断是不是需要进行真实DOM的替换,这时候,虚拟DOM就会生成一个新的虚拟节点对象vnode,它有一个对象的旧的虚拟节点对象oldvnode,(这里oldvnode和vnode就对应上面patch函数的两个参数)下面就是要判断这两个节点是不是发生改变了。

旧节点不存在

首先如果压根旧节点不存在,需要重新生成一个节点,那么什么判断都不需要做,直接生成就好了:

if(!oldvnode){
	createElement(vnode);
}

判断两个节点基本属性是否一致

如果旧节点存在,那么就需要判断两个节点的基本属性,假如两个节点,一个是div,另外一个是span,那压根就不用比了,直接生成新节点替换就成了。

说说比较重要的属性:

tag 属性即这个vnode的标签属性:div、span、p等等
data 属性包含了最后渲染成真实dom节点后,节点上的class,attribute,style以及绑定的事件
children 属性是vnode的子节点
text 属性是文本属性
elm 属性为这个vnode对应的真实dom节点
key 属性是vnode的标记,这个key在diff算法中非常重要

所以在进行Diff算法前,需要判断一下这些重要属性是不是一样的。

function sameVnode (a, b) {
	return (
		a.key === b.key &&
		a.tag === b.tag &&
		a.isComment === b.isComment &&
		isDef(a.data) === isDef(b.data) &&
		sameInputType(a, b)
	)
}

Diff算法真实应用

了解一下Diff的核心:

1. 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构
2. 同一层级的一组节点,他们可以通过唯一的id进行区分

简单来讲,就是Vue会按照真实DOM生成一个虚拟DOM,之后当某节点数据发生改变后,虚拟DOM就会生成一个新的节点,然后自己的新节点和旧节点比较一下,如果发生改变了,那么就会直接在真实DOM上进行替换,俗称打补丁。

到了patchVnode方法,说明新老节点为同一节点,让我们来看看patchVnode函数,其实diff算法就包含在patchVnode函数里面:

这其中的diff过程中又分了好几种情况,oldCh为oldVnode的子节点,ch为Vnode的子节点:

新老节点一样,直接返回;
老节点有子节点,新节点没有:删除老节点的子节点;
老节点没有子节点,新节点有子节点:新节点的子节点直接append到老节点;
都只有文本节点:直接用新节点的文本节点替换老的文本节点;
都有子节点:updateChildren(这个函数应该是接下来最重要的)

patchVnode(oldVnode, vnode) // diff在这里

function patchVnode (oldVnode, vnode) {
	const el = vnode.el = oldVnode.el  //  找到对应的真实DOM
	let oldCh = oldVnode.children, ch = vnode.children 
	if (oldVnode === vnode) return  // 如果新老节点相同,直接返回
	if (oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text) {
		// 如果新老节点都有文本节点且不相等,那么新节点的文本节点替换老节点的文本节点
		api.setTextContent(el, vnode.text) 
	}else {
		updateEle(el, vnode, oldVnode)
		if (oldCh && ch && oldCh !== ch) {
			// 如果新老节点都有子节点,执行updateChildren比较子节点
			updateChildren(el, oldCh, ch)
		}else if (ch){
			// 如果新节点有子节点而老节点没有子节点,那么将新节点的子节点添加到老节点上
			createEle(vnode)
		}else if (oldCh){
			//如果新节点没有子节点而老节点有子节点,那么删除老节点的子节点
			api.removeChildren(el)
		}
   }
}

在这里插入图片描述
整个流程下来,上面最开始的patch函数就讲解完了,那么patch函数什么时候触发呢???????????

当数据发生改变时,双向数据绑定中的set方法(详情请参考数据驱动章节)会让调用Dep.notify通知所有订阅者Watcher,订阅者就会调用patch给真实的DOM打补丁,进行页面的真正更新。

key

当我们在Vue组件中使用v-for循环的时候,假如我们在循环中间新增了一个数据,那么理论上虚拟DOM会在新增之后进行一个个节点的替换,其实这样很浪费,因为就是新增了一个节点,完全没必要前面替换,然后还需要新增一个节点,浪费时间,而且新旧对比还会发生没必要的补丁,更新真实DOM还费时间。

在Vue组件我们利用循环就会使用key,key在虚拟DOM里面绑定的是节点ID,然后把数据的ID给节点ID,这样子就可以使用diff算法时不会替换前面的循环,直接新增一个节点,然后真实DOM也就增加一个节点,省了好多时间。

Vue.nextTick

因为我们更改一段代码,让页面中的DOM进行更新时,节点因为虚拟DOM的存在不会马上就去更新,中间有一段比较的过程,所以读取会发现根本没有数据更改,这时候Vue.nextTick就出来了。

Vue.nextTick() 是一种异步操作函数,它会在真实DOM更新之后才执行回调函数。

准确来说就是函数返回一个Promise对象,之后就是then来回调访问真实DOM了。

vuejs从入门到精通(一)笔记,学习:尚硅谷Vue2.0+Vue3.0全套教程 初始vue,vue是什么?谁开发的?vue的特点是什么?怎么使用? 阅读详情

相关推荐

ECB oracle——attack

基于ECB oracle的攻击方案前言什么是ECB方案步骤1.确定块大小和明文大小2.暴力破解求明文脚本代码 前言 参考文章:Breaking ECB by prepending your own message. 环境地址:ECB oracle 什么是ECB 分组密码中AES的一种模式(其他还有:CBC、ECB、CTR、OCF、CFB)如图每一块加密是分开的。 方案步骤 1.确定块大小和明文大小 先用一个字符"a"去encrypt返回32个字节的数据(64位16进制)依次用"aa",“aaa”…去en

weixin_44617902的博客 1311

vue的虚拟dom返回html,【Vue】基础(虚拟DOM & 响应式原理)

Vue一如分算需上来处一定迹面数一跳这件我子作的响应式大概会经过新直能分支调二浏页器朋代说,事刚需求下面几个阶段1. 器打好基下是求的响的可域适的一的近重交的使用 Object.defineProperty 把属性全部转为getter/到二新,为都础过过发等宗和发制数事前理业待很理断到屏能击示和站公下图以使箭分以近一步调现了喜知进setter2.览页些求时是过解些这确如目前例总站回广随 属性变更时...

weixin_42549037的博客 823

从理论到实践:笛卡尔空间阻抗控制的实现挑战与变体解析

本文深入探讨了笛卡尔空间阻抗控制的核心原理、工程实现中的五大挑战及经典变体实战解析。通过详细的数学建模和实际案例分析,揭示了阻抗控制在工业机器人、医疗设备等领域的应用价值,特别是在力感知精度、动力学模型校准和实时计算等方面的关键技术突破。

weixin_30952535的博客 449

Vue中的虚拟DOM

在聊虚拟DOM 之前,我们先来说说真实DOM。真实DOM渲染浏览器的步骤如下: 第一步,用HTML分析器,分析HTML元素,构建一颗DOM树。 第二步,用CSS分析器,分析CSS文件和元素样式,生成页面样式表。 第三步,将DOM树和样式表,关联起来,构建一颗Render树。每个DOM节点都有attach方法,接受样式信息,返回一个render对象。这些render对象最终会被构建成一颗Render...

Web_Developer_24的博客 315

5QI(5G QoS Identifier)

此外,5QI与网络切片(Network Slicing)密切相关,网络切片允许网络运营商在物理网络内部创建虚拟网络,为不同的客户和用例提供定制化服务和QoS。5QI(5G QoS Identifier)在5G网络中用于标识不同的服务质量要求,它允许网络对不同的数据流进行优先级划分和资源分配。:5QI的实施需要对5G网络的QoS参数有深入的理解,包括延迟、吞吐量、数据包丢失率等,这对技术人员提出了较高的要求。不是所有的5G设备都支持5QI的全部功能,这可能会限制5QI应用的广泛性。

记录有价值的内容 6534

告别‘耀斑’降落:手把手教你用PX4+激光测距仪实现固定翼精准自动着陆

本文详细介绍了如何利用PX4飞控与激光测距仪实现固定翼无人机的精准自动着陆,解决传统气压计在低空环境下的测量误差问题。通过硬件选型、安装要点、PX4参数配置及实战调校,帮助开发者实现厘米级高度感知,优化降落曲线,提升着陆稳定性与安全性。

weixin_30336061的博客 520

vue的虚拟DOM

vue的虚拟dom

TeFuir__Lv的博客 2488

统信UOS/麒麟ARM桌面版,不联网也能用Docker部署MySQL 5.7(离线部署详解)

本文详细介绍了在统信UOS/银河麒麟ARM桌面版系统中,如何离线部署MySQL 5.7的完整流程。通过Docker技术实现环境隔离和依赖封装,解决了封闭网络环境下的部署难题,包括资源准备、系统配置、容器化部署及安全加固等关键步骤,为政企和科研场景提供实用解决方案。

weixin_30892037的博客 230

vue虚拟DOM详解

1.虚拟DOM的概念 虚拟DOM的概念是通过状态生成一个虚拟节点树,然后使用虚拟节点数进行渲染。在渲染之前,会使用新生成的虚拟节点和上一次生成的虚拟节点进行对比,只渲染不同的部分 2.vue中的虚拟DOM vue中状态变化时,只能通知到组件,组件内部的变化需要通过虚拟DOM去进行比对与渲染 在vue中,我们使用模板来描述状态与DOM之间的映射关系。vue通过编译将模板转换成渲染函数,执行渲染函数就可以得到一个虚拟节点树,使用虚拟节点数就可以渲染页面 虚拟DOM在vue中主要提供与真实节点对应的虚拟

Goodbye_的博客 9737

从一只龙虾到一支团队:OpenClaw 单 Bot 多 Agent 配置实践

单 Bot 多 Agent只有一个对外的聊天入口(飞书 Bot)内部有多个独立的 AI Agent,各司其职主 Agent(总指挥)负责接收任务并分配给子 Agent子 Agent 完成任务后将结果返回给主 Agent角色Agent ID职责使用场景🎯 总指挥main-agent统筹协调,任务分发接收所有用户请求✍️ 笔杆子内容创作公众号、博客、小红书🔬 参谋canmou深度研究竞品分析、市场调研📋 运营官operations运营管理邮件、日历、社交媒体。

Maynor的博客 1084

大数据分析工具Power BI(二):Power BI下载安装和模块介绍

首先在Microsoft官方网站上下载PowerBI Desktop,然后进行安装。id=58494点击"Next"后会弹出下载框,进行下载即可,下载好的PowerBI名称为"PBIDesktopSetup_x64.exe",也可以在"资料"中获取安装包,双击安装包即可安装。

Lansonli(蓝深李)的博客 2321

vue中的虚拟dom

介绍了vue中的虚拟DOM的实现原理,以及v-for指令中为什么要设置key值

九仞山的专栏 6064

深度强化学习在足式机器人中的应用 (一):基础原理与仿真环境

我们将首先深入探讨其背后的核心挑战与技术栈,然后详细推导机器人学和强化学习的基本数学原理,特别是剖析在机器人控制领域表现卓越的PPO算法。下面的独立Python脚本展示了Isaac Gym的基本API用法,加载一个Go1机器人(假设URDF已准备好),并让它执行一个简单的预设动作(正弦波运动),以此来熟悉仿真流程。:代码的核心是直接操作GPU上的PyTorch张量,避免了CPU和GPU之间的数据拷贝,这是实现高性能的关键。:所有计算(如伪策略中的正弦波计算)都应该是向量化的,一次性为所有。

VectorShift的博客 228

【Vue面试题二十二】、什么是虚拟DOM?如何实现一个虚拟DOM?说说你的思路

虚拟 DOM ()这个概念相信大家都不陌生,从React到Vue,虚拟DOM为这两个框架都带来了跨平台的能力(和Weex实际上它只是一层对真实DOM的抽象,以JavaScript对象 (VNode节点) 作为基础的树,用对象的属性来描述节点,最终可以通过一系列操作使这棵树映射到真实环境上在Javascript对象中,虚拟DOM表现为一个Object对象。并且最少包含标签名 (tag)、属性 (attrs) 和子元素对象 (children) 三个属性,不同框架对这三个属性的名命可能会有差别创建虚拟。

日常笔记 | 干货分享 | 毕设源码 | 毕设指导 | 答辩指导 768

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

十二、虚拟 DOM 和 render() 函数(1)

● 虚拟DOM ● render()函数

走在bug的路上 1万+

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

面试 Vue 框架八股文十问十答第十二期

面试必备八股文!内容包含:Java基础、Java框架、Git命令、JVM、多线程、消息队列、微服务、Linux、数据库、Redis缓存、算法、Vue、React、前端性能优化等八股文。

qq_67358181的博客 1661

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

虚拟dom与diff算法

虚拟dom与diff算法 以下为自己总结内容,欢迎其他程序员小伙伴一起交流谈论! 1、概念引入 大量的dom操作会使性能降低,而且花费的时间更多,为此,为了减少dom操作,提高性能,我们应该先操作数据,再去操作dom,因此,前端引入了虚拟dom,即vdom Vue是一种MVVM框架,Vue高性能的原因之一就是vdom 2、什么是虚拟dom(vdom) 它是一个Object对象模型,用来模拟...

wxxuejishuangxia的博客 240

Vue进阶(八十二):updated 应用详解

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 无论是组件本身的数据变更,还是从父组件接收到的 props 或者从vuex里面拿到的数据有变更,都会触发虚拟 DOM 重新渲染和打补丁,并在之后调用 updated。 有个值得注意的地方,举例说明: 例子 <template> <div> <div v-for="(ite...

IT全栈 华强工作室 2万+

Vue前端面试整理(持续更新)

在 Vue.js 中,为什么使用函数而不是对象来定义 data 呢?这其实涉及到 JavaScript 的闭包和引用类型的特性。data: {这样做虽然看起来简单直观,但会存在一个问题——所有组件实例共享同一个 data 对象,这可能导致数据的不可预料的变化和冲突。为了避免这个问题,Vue.js 推荐我们将 data 定义为一个返回对象的函数,而不是一个普通的对象。这样每个组件实例都会有自己独立的 data 对象,相互之间不会相互影响。

m0_67521703的博客 1371

Vue进阶(四十七):面试必备:2026 Vue经典面试题总结(含答案)

MVVM是的缩写。MVVM是一种设计思想。Model层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View代表UI 组件,它负责将数据模型转化成UI展现出来,ViewModel是一个同步View和Model的对象。在MVVM架构下,View和Model之间并没有直接的联系,而是通过ViewModel进行交互,Model和ViewModel之间的交互是双向的, 因此View数据的变化会同步到Model中,而Model数据的变化也会立即反应到View上。ViewModel。

IT全栈 华强工作室 22万+

Vue原理「十二」-- vdom和diff算法 *****

diff 算法概述 diff即对比,是一个广泛的概念,如linux diff、git diff 两个JS对象也可以做diff 两颗树做diff,如vdom diff 树diff 时间负责度是o(n^3) 第一,遍历tree1;第二,遍历tree2 第三,排序 1000个节点,要计算 1亿次,算法不可用 优化时间复杂度到o(n) 之比较同一级,不跨级比较 tag不相同,则直接删掉重建,不再深度比较 tag和key两者都相同,则认为是相同节点,不再深度比较 patchVnode() diff算法总结 pa

louShuMei 的博客 603

Vue3 知识点总结

当数据更改时,将重新编译成虚拟DOM树,然后对前后两棵树进行比对(diff算法),仅将差异部分反映到真实DOM,这样既可最小程度的改动真实DOM,提升页面效率。知识点:Axios、Vuex、Stylus、插件、Vue Router、异步组件、递归组件、公用组件;{{content}} : 获取 vue里面data 里面的数据值,属双向绑定。实战项目:环境搭建、Git、数据模拟、本地开发;$就是个命名,帮你区分vue应用自身的属性,而不是你自己定义的属性。将生成的真实DOM树,放置到某个元素位置,称之为。

weixin_40011280的博客 2117

十二、虚拟 DOM 和 render() 函数(2)

● 用普通 JavaScript 代替模板功能 ○ v-if 和 v-for ○ v-model ○ v-on ○ 事件和按键修饰符 ○ 插槽 ● JSX ● 实例:帖子列表

走在bug的路上 1万+

vuejs常用指令_【必会】十二个VueJs常见面试题

对于MVVM的理解?MVVM 是 Model-View-ViewModel 的缩写。Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。View代表UI 组件,它负责将数据模型转化成UI 展现出来。ViewModel监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。在MVVM架构下,View 和 ...

weixin_29663547的博客 180

前端面试vue综合面试题持续更新...

风尚云网-vue相关综合面试题(不看后悔),前端人员必看 Fashion cloud -vue related comprehensive interview questions (no regrets), front-end personnel must see

你不追逐时代,时代就会反噬你,我是风尚,一个有趣的灵魂 2822

Vue:(十二)列表渲染

Vue之列表渲染

weixin_41377877的博客 415
上一篇: Javascript教程十————DOM
下一篇: axios教程
ruby___ruby
博客等级 码龄9年 2粉丝 28原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值