vue的虚拟DOM和diff算法

news/2024/11/24 3:32:03/

虚拟DOM和diff算法密不可分,
虚拟dom,它本身就是一个 JavaScript 对象,为解决DOM操作非常耗时,把DOM转换为虚拟DOM,DOM操作转换为js计算,js执行速度较快。
diff算法在vue中被优化为O(n)的时间复杂度,diff算法是比较两个vnode,计算出最小的变更。

一,虚拟DOM

1.虚拟DOM结构

虚拟节点就是用一个对象来描述一个真实的DOM元素。首先将 template(真实DOM)先转成 ast, ast树通过 codegen生成 render函数, render函数里的 _c方法将它转为虚拟dom.
用js模仿DOM结构

<div id="div1" class="container"><p>vdom</p><ul style="font-size: 20px;"><li>a</li></ul>
</div>

转换为虚拟DOM对应的js对象:

{tag: 'div'props: {className: 'container'id: 'div1'}children: [{tag: 'p'children: 'vdom'}{tag: 'ul'props: {style="font-size: 20px;"}children: [{tag: 'li'children: 'a'}]}]
}

2.虚拟DOM如何生成

组件模板template, 这个模板会被编译器 - compiler编译为渲染函数,在接下来的挂载(mount)过程中会调用render函数,返回的对象就是虚拟dom。但它们还不是真正的dom,所以会在后续的patch过程中进一步转化为dom。

// 插值
const template = `<p>{{message}}</p>`
with(this){return _c('p',[createTextVNode(toString(message))])}
// h -> vnode
// createElement(_c) -> vnode
// this -> const vm = new Vue({....})

3.虚拟DOM解析过程

参照虚拟DOM结构

  • 首先对将要插入到文档中的 DOM 树结构进行分析,使用 js 对象表示,包含 TagName、props 和 Children 等这些属性。然后将这个 js 对象树给保存下来,最后再将 DOM 片段插入到文档中。
  • 当页面的状态发生改变,需要调整DOM结构,首先根据变更的状态,重新构建起一棵对象树,然后将这棵新的对象树和旧的对象树进行比较,记录下两棵树的的差异。
  • 最后将记录的有差异的地方应用到真正的 DOM 树中去,这样视图就更新了。

二,diff算法

vue的vdom是模仿snabbdom写的,可以去github上看

1.diff算法的原理

只比较同级,不跨域比较;

如果tag不相同,直接删除重建,不再深度比较
在这里插入图片描述

如果tag和key都相同,默认是一样的节点,也不再深度比较

2.diff算法执行流程

1.首先用patch方法对比新旧vnode
在这里插入图片描述

patch参数有两种情况,一个参数是一个elementDOM元素,第二个是vnode,也有可能两个都是vnode,作用是第一个是直接渲染到一个空的DOM元素中,第二个是更新已有的内容
在这里插入图片描述

● 首先会处理下第一个参数如果不是vnode,那么会创建一个空的vnode,关联到这个DOM元素
在这里插入图片描述

● 然后判断是否是相同的vnode(通过判断两个vnode的key和select都相同)
在这里插入图片描述
如果都没有key,undefined===undefined //true。在循环体v-for必须传key

● 最后判断是不相同的两个vnode,就直接删掉重建,就不再对比了
在这里插入图片描述

2.然后在patch函数中调用patchVnode对比新旧children
patchVnode函数,接收两个参数,一个旧的vnode,一个新的vnode
在这里插入图片描述
tips:设置Vnode.elem:把旧的元素对应的DOM元素赋给新的,否则新的vDOM不知道更新哪个。

获取两个的children,然后把新旧children进行对比,主要是几种情况:
在这里插入图片描述在这里插入图片描述

● 两者都有children的时候,我们要通过updateChilren通过key进行children之间的对比;

● 如果是新的children有值,旧的children没有值,我们要通过addVnode进行添加

● 如果是新的children没有值,旧的children有值,那我们要通过removeVnodes给移除掉

3.key的作用

在这里插入图片描述
不使用key,老的节点全部删掉,插入新的节点。使用key,会比对key,直接相同移过来就好了。key不能使用index,因为不管数组的顺序怎么颠倒,index 都是 0, 1, 2…这样排列,导致 Vue 会复用错误的旧子节点。


http://www.ppmy.cn/news/5057.html

相关文章

CANoe-VN5000接口卡在Network-based模式下典型的应用场景

1、Network-based mode说明 CANoe软硬件都需要设置为Network-based mode 软件从CANoe12版本支持Network-based模式(CANoe12时称为Port-based mode,从13开始改为Network-based mode) 硬件从VN5000系列开始支持Network-based模式,VN5610A和VN5640设备需要确保切换到Network…

js 时间戳增加1小时或 N 小时

一小时的时间戳 3,600,000 一天的时间戳 86400000 一个月的时间戳 2592000000 一年的时间戳 31104000000 const t new Date().getTime(); //1小时时间戳&#xff08;几小时就乘以几...1.2.3&#xff09; const t1 t (3600 * 1000 * 1)

跨平台移植 | 如何尽快适应大型C++项目?

问题 题主现在刚加入一个公司&#xff0c;目前做的工作是将一个大型的C项目从依赖MFC的环境下移植到Mac环境下&#xff0c;代码几千万行是有的。第一次接触这种规模的项目&#xff0c;应该怎么让自己尽快上手。项目里从上世纪九十年代的代码到现在的代码&#xff0c;文件名有全…

把d盘的文件删除了,怎么恢复?d盘的文件删除了怎么找回

把d盘的文件删除了,怎么恢复&#xff1f;通常&#xff0c;我们删除d盘文件的情况是不一样的&#xff0c;可能是通过不同的方法删除的&#xff0c;针对不同的删除方式&#xff0c;那么要恢复这些文件的方法也是不同的&#xff0c;小编按删除方式和时间来给大家进行详细的讲解。 …

全网最详细的网络安全入门教程,一篇文章满足你

随着当下正在发生的互联网革命&#xff0c;以及乌俄局势的网络战&#xff0c;网络安全行业已经受到更多人的关注&#xff0c;而这个行业的人才缺口将继续呈指数型扩张。借用行业内某大咖的一句话“网络安全行业的人才成材率极低”&#xff0c;究其原因还是因为网络安全从业者所…

数据结构和算法(四)--高级排序

目录 二、高级排序 2.1、希尔排序 2.2、归并排序 2.2.1、递归 2.2.2、归并排序 3、快速排序 4、排序的稳定性 数据结构和算法(三)--排序 二、高级排序 冒泡排序&#xff0c;选择排序&#xff0c;插入排序&#xff0c;最坏的时间复杂度都是O(N^2)&#xff0c;而平方阶&…

SAP MDG —— License的度量方式

文章目录前言概念业务定义SAP MDG, ConsolidationSAP MDG, Central GovernanceSAP MDG, Data quality management“度规”是什么MDG&#xff1a;财务对象MDG&#xff1a;自定义对象MDG&#xff1a;供应商主数据对象MDG&#xff1a;客户主数据对象MDG&#xff1a;业务伙伴对象MD…

深度学习基础知识---梯度弥散 梯度爆炸

目录 1 梯度弥散、梯度爆炸的成因 2 解决方式 2.1.pretrainfinetune 2.2 梯度裁剪 2.3 权重正则化 2.5 Batch Normalization正则化 2.6 残差结构 shortcut 2.7 LSTM 1 梯度弥散、梯度爆炸的成因 神经网络的层&#xff08;主要是隐藏层&#xff09;越多&#xff0c;对…