Vue中虚拟DOM的理解

Virtual DOM是一棵以JavaScript对象作为基础的树,每一个节点称为VNode,用对象属性来描述节点,实际上它是一层对真实DOM的抽象,最终可以通过渲染操作使这棵树映射到真实环境上,简单来说Virtual DOM就是一个Js对象,用以描述整个文档。

描述

在浏览器中构建页面时需要使用DOM节点描述整个文档。

<div class="root" name="root">
<p>1</p>
<div>11</div>
</div>

如果使用Js对象去描述上述的节点以及文档,那么便类似于下面的样子,当然这不是Vue中用以描述节点的对象,Vue中用以描述一个节点的对象包括大量属性,例如tagdatachildrentextelmnscontextkeycomponentOptionscomponentInstanceparentrawisStaticisRootInsertisCommentisCloned等等,具体的属性可以参阅Vue源码的/dev/src/core/vdom/vnode.js

{
type: "tag",
tagName: "div",
attr: {
className: "root"
name: "root"
},
parent: null,
children: [{
type: "tag",
tagName: "p",
attr: {},
parent: {} /* 父节点的引用 */,
children: [{
type: "text",
tagName: "text",
parent: {} /* 父节点的引用 */,
content: "1"
}]
},{
type: "tag",
tagName: "div",
attr: {},
parent: {} /* 父节点的引用 */,
children: [{
type: "text",
tagName: "text",
parent: {} /* 父节点的引用 */,
content: "11"
}]
}]
}

Vue中首先会解析template中定义的HTML节点以及组件节点,为render作准备,在解析的过程中会生成_c()_v()等函数,其作为renderHelpers用以创建节点,_v()函数就是用以创建文本节点,而_c()函数就是用以创建VNode节点的,这个函数其实就是Vue中定义的_createElement()函数,通过这个函数来确定创建的是普通节点还是组件节点,具体可以在Vue源码中/dev/src/core/vdom/create-element.js以及/dev/src/core/vdom/create-element.js查阅,当解析完成之后,便能够生成render函数,而当render函数执行后便返回了VNode节点组成的虚拟DOM树,树中的每一颗节点都会存储渲染的时候需要的信息,之后便是通过diff算法以及patch过程的createElmpatchVnode渲染到真实DOM

if (typeof tag === 'string') {
let Ctor
ns = (context.$vnode && context.$vnode.ns) || config.getTagNamespace(tag)
if (config.isReservedTag(tag)) {
// platform built-in elements
if (process.env.NODE_ENV !== 'production' && isDef(data) && isDef(data.nativeOn)) {
warn(
`The .native modifier for v-on is only valid on components but it was used on <${tag}>.`,
context
)
}
vnode = new VNode(
config.parsePlatformTagName(tag), data, children,
undefined, undefined, context
)
} else if ((!data || !data.pre) && isDef(Ctor = resolveAsset(context.$options, 'components', tag))) {
// component
vnode = createComponent(Ctor, data, context, children, tag)
} else {
// unknown or unlisted namespaced elements
// check at runtime because it may get assigned a namespace when its
// parent normalizes children
vnode = new VNode(
tag, data, children,
undefined, undefined, context
)
}
} else {
// direct component options / constructor
vnode = createComponent(tag, data, context, children)
}

作用

渲染真实DOM的过程中开销是很大的,例如当有时候修改了某个数据或者属性,如果直接渲染到真实DOM上可能会引起整个DOM树的重绘与回流,而diff算法能够只更新修改的那部分DOM结构而不更新整个DOM,这里需要说明的是操作DOM结构的速度并不慢,而性能消耗主要是在浏览器重绘与回流的操作上。

当选用diff算法进行部分更新的时候就需要比较旧DOM结构与新DOM结构的不同,此时就需要VNode来描述整个DOM结构,首先根据真实DOM生成Virtual DOM,当Virtual DOM某个节点的数据改变后会生成一个新的Vnode,然后通过newVNodeoldVNode进行对比,发现有不同之处便进行patch修改于真实DOM,然后使旧的Virtual DOM赋值为新的Virtual DOM

简单来说建立Virtual DOM的目的是减少对于整个DOM的操作,通过建立Virtual DOM来追踪如何改变真实DOM,从而实现更高效地更新节点。

使用Virtual DOM同样也是有部分缺点,代码更多,体积更大,内存占用增大,对于小量的单一的DOM修改使用虚拟DOM成本反而更高,但是整体来说,使用Virtual DOM是优点远大于缺点的。

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://juejin.im/post/6844903607913938951
https://segmentfault.com/a/1190000018211084
https://github.com/lihongxun945/myblog/issues/32
https://cloud.tencent.com/developer/article/1004551
https://www.cnblogs.com/fundebug/p/vue-virtual-dom.html
https://blog.csdn.net/u010692018/article/details/78799335/

Vue中虚拟DOM的理解的更多相关文章

  1. Vue中diff算法的理解

    Vue中diff算法的理解 diff算法用来计算出Virtual DOM中改变的部分,然后针对该部分进行DOM操作,而不用重新渲染整个页面,渲染整个DOM结构的过程中开销是很大的,需要浏览器对DOM结 ...

  2. Vue中获取dom元素

    Vue.js虽然说是数据驱动页面的,但是有时候我们也要获取dom对象进行一些操作. vue的不同版本获取dom对象的方法不一样 Vue.js  1.0版本中,通过v-el绑定,然后通过this.els ...

  3. 第七十六篇:ref引用(在vue中引用Dom的方法)

    好家伙, 引子: jQuery简化了程序员操作DOM的过程 vue 优势:MVVM 在vue中,程序员不需要操作DOM.程序员只需要把数据维护好即可!(数据驱动视图) 那么若要在vue中操作dom,这 ...

  4. 最近发现了一篇讲解Vue的虚拟DOM,diff很棒的文章,特定记录转载一下

    本文章是转载的,为了方便以后复习,特地记录一下.他人请去原地址观看!!! 文章原地址:https://blog.csdn.net/m6i37jk/article/details/78140159 作者 ...

  5. Vue之虚拟DOM

    一.真实DOM和其解析流程? 浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTM ...

  6. Vue原理--虚拟DOM

    为什么需要虚拟DOM? 如果对前端工作进行抽象的话,主要就是维护状态和更新视图,而更新视图和维护状态都需要DOM操作.其实近年来,前端的框架主要发展方向就是解放DOM操作的复杂性. 运行js的速度是很 ...

  7. Virtual DOM 虚拟DOM的理解(转)

    作者:戴嘉华 转载请注明出处并保留原文链接( #13 )和作者信息. 目录: 1 前言 2 对前端应用状态管理思考 3 Virtual DOM 算法 4 算法实现 4.1 步骤一:用JS对象模拟DOM ...

  8. vue之虚拟DOM、diff算法

    一.真实DOM和其解析流程? 浏览器渲染引擎工作流程都差不多,大致分为5步,创建DOM树——创建StyleRules——创建Render树——布局Layout——绘制Painting 第一步,用HTM ...

  9. vue 的虚拟 DOM 有什么好处?

    vue 中的虚拟DOM有什么好处?快! 首先了解浏览器显示网页经历的5个过程 1.解析标签,生成元素树(DOM树) 2.解析样式,生成样式树 3.生成元素与样式的关系 4.生成元素的显示坐标 5.显示 ...

  10. Vue中keep-alive组件的理解

    对keep-alive组件的理解 当在组件之间切换的时候,有时会想保持这些组件的状态,以避免反复重渲染导致的性能等问题,使用<keep-alive>包裹动态组件时,会缓存不活动的组件实例, ...

随机推荐

  1. linux环境C语言实现:h265与pcm封装成AVI格式

    ​ 前言 不知道是处于版权收费问题还是什么原因,H265现在也并没有非常广泛的被普及.将h265数据合成AVI的资料现在在网上也基本上没有.使用格式化工厂工具将h265数据封装成AVI格式,发现它在封 ...

  2. 使用requests爬虫遇到的一个奇葩的问题:UnicodeEncodeError: 'latin-1' codec can't encode character

    每一位成功的程序员,背后也许都站着无数的秃头的男人--为其提供各种开发工具&代码库,当然也包括-- 各种玄学bug-- 玄学的开端 最近在用Python做一个爬虫项目的时候遇到一个很奇怪的问题 ...

  3. JVM大页内存的学习与使用

    JVM大页内存的学习与使用 原理和背景 操作系统是计算机的重要组成部分. 现代的操作系统一般都采用 段页式内存管理. 段一般是为了管理和权限 页主要是为了虚拟内存和物理内存的映射. 分页管理可以让物理 ...

  4. [转帖]11GR2数据库审计日志自动清理

    审计日志如果把SYSTEM表空间撑爆,也会导致数据库停摆,且11g默认审计是开启状态. 今天就遇到了这样的情况,写了下面脚本来实现自动清理工作,记录操作过程. TRUNCATE TABLE SYS.A ...

  5. [转帖]OJDBC版本区别 [ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别]

    classes12.jar,ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别,之间的差异 在使用Oracle JDBC驱动时,有些问题你是不是通过替换不同版本的Oracle  ...

  6. [转帖]12.计算机网络---iptables防火墙管理工具

    文章目录 一.防火墙基础知识 1.1 防火墙是什么? 1.2 iptables基础知识 1.3 netfilter和iptables的关系: 1.4 新型防火墙工具:firewalld 二.iptab ...

  7. js引起的 xxxx of null

    在 vue 中操作 dom 元素的时候,报错 style of null 这个报错的原因,跟你代码的健壮性有关了; 这样就不会报错了 if( document.querySelectorAll(&qu ...

  8. 【发现一个问题】使用 fastcgo 导致额外的 `runtime._System` 调用的消耗

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 为了避免 cgo 调用浪费太多资源,因此使用了 fastc ...

  9. Fabric网络升级(一)

    原文来自这里. 本章节主要介绍如何从之前的版本或其他长期支持版本升级至最新版. 从2.1升级到2.2 Fabric v2.1和v2.2都是稳定版,以bug修复和其它形式的代码加固位置.因此,升级不需要 ...

  10. 在C#或python中使用xpath解析xml

    记几个笔记 文件后缀不一定要.xml,可以是任意后缀,只要内容是符合xml和格式即可解析出来 文件编码需要是utf-8,python和c#都需要,或者xml文件头有这样一句:<?xml vers ...