Javascript 虚拟 DOM详解

 更新时间:2021年12月09日 14:33:04   作者:ZhangLiangXWZ  
这篇文章主要为大家介绍了Javascript 虚拟 DOM,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

什么是虚拟 dom?

虚拟 dom 本质上就是一个普通的JS对象(mounted 中打印 this. _vnode 就是该对象内容),用于描述视图的界面结构

在vue中,每个组件都有一个render函数,每个render函数都会返回一个虚拟dom树,这也就意味着每个组件都对应一棵虚拟DOM树

在这里插入图片描述

vnode 是一个普通的 JS 对象,用于描述界面上应该有什么,比如:

var vnode = {
  tag: "h1",
  children: [
    { tag: undefined, text: "第一个vue应用:Hello World"}
  ]
}

上面的对象描述了:

有一个标签名为 h1 的节点,它有一个子节点,该子节点是一个文本,内容为「第一个vue应用:Hello World」

为什么需要虚拟dom?

在vue中,渲染视图会调用render函数,这种渲染不仅发生在组件创建时,同时发生在视图依赖的数据更新时。如果在渲染时,直接使用真实DOM,由于真实DOM的创建、更新、插入等操作会带来大量的性能损耗,从而就会极大的降低渲染效率。

因此,vue在渲染时,使用虚拟dom来替代真实dom,主要为解决渲染效率的问题。

对比创建js对象和真实 dom 对象效率:

在这里插入图片描述

结果:

在这里插入图片描述

创建一个真实的 dom 会伴随着创建许多的属性

在这里插入图片描述

虚拟dom是如何转换为真实dom的?

在一个组件实例首次被渲染时,它先生成虚拟dom树,然后根据虚拟dom树创建真实dom,并把真实dom挂载到页面中合适的位置,此时,每个虚拟dom便会对应一个真实的dom。如果页面只会刷新一次,后续不会有数据更新等问题的情况下,用虚拟 dom 的方式是比直接显示真实 dom 效率低的。

如果一个组件受响应式数据变化的影响,需要重新渲染时,它仍然会重新调用render函数,创建出一个新的虚拟dom树,用新树和旧树对比,通过对比,找出差异,然后仅更新差异部分的虚拟dom节点,最后,这些更新过的虚拟节点,会去修改它们对应的真实dom

这样一来,就保证了对真实dom达到最小的改动。

在这里插入图片描述

模板和虚拟dom的关系

vue框架中有一个compile(编译)模块,它主要负责将模板转换为render函数,而render函数调用后将得到虚拟dom。

编译的过程分两步:

1.将模板字符串转换成为AST(抽象语法树:用js树形结构来描述我们原始的代码;在线工具:https://astexplorer.net/

2.将AST转换为render函数

vue 模板并不是真实的 DOM,它会被编译为虚拟 DOM

<div id="app">
  <h1>第一个vue应用:{{title}}</h1>
  <p>作者:{{author}}</p>
</div>

上面的模板会被编译为类似下面结构的虚拟 DOM

{
  tag: "div",
  children: [
    { tag: "h1", children: [ { text: "第一个vue应用:Hello World" } ] },
    { tag: "p", children: [ { text: "作者:袁" } ] }
  ]
}

如果使用传统的引入方式(script src="...vue.js"),则编译时间发生在组件第一次加载时,这称之为运行时编译。

如果是在vue-cli的默认配置下,编译发生在打包时(npm run build),打包之后就没有模板只有 render 函数了,这称之为模板预编译。

编译是一个极其耗费性能的操作,预编译可以有效的提高运行时的性能,而且,由于运行的时候已不需要编译,vue-cli在打包时会排除掉vue中的compile模块,以减少打包体积

打包时是否需要包含 compile 模块,是通过 vue.config.js 中的 runtimeCompiler: true 来控制的,默认 false,不包含。不建议更改该配置

模板的存在,仅仅是为了让开发人员更加方便的书写界面代码

vue最终运行的时候,最终需要的是render函数,而不是模板,因此,模板中的各种语法,在虚拟dom中都是不存在的,它们都会变成虚拟dom的配置

在 vue-cli 中如果同时存在 template 和 render, 由于存在一个打包过程,其中的模板预编译会生成 render 覆盖原有的 render 函数

在 vue 中如果同时存在 template 和 render,一定是以 render 为准

虚拟 DOM 树会最终生成为真实的 DOM 树

在这里插入图片描述

vue通过以下逻辑生成vnode tree:

在这里插入图片描述

注意:虚拟节点树必须是单根的

注入

在这里插入图片描述

vue会将以下配置注入到vue实例:

  • data:和界面相关的数据
  • computed:通过已有数据计算得来的数据,将来详细讲解
  • methods:方法

模板中可以使用vue实例中的成员

为了防止名称冲突。因为会将data中数据代理给vue,假如说我们自己写的data名称和vue中自带的属性冲突了,那么就会覆盖vue内部的属性,所以vue会把自己内部的属性成员名称前加上 或 , 如 果 加 上 的 是 或_,如果加上的是 或,​如果加上的是,代表是我们可以使用的,如果加上的是_,是vue自己内部使用的方法或属性,我们不需要调用

挂载

将生成的真实 DOM 树,放置到某个元素位置,称之为挂载

挂载的方式:

1.通过el:"css选择器"进行配置

2.通过vue实例.$mount(“css选择器”)进行配置

完整流程

  • 实例被创建: new Vue()
  • 注入完成之后才会有响应式,能监听到数据变化
  • 编译生成虚拟 DOM 树:首先找 render 函数,没有就找模板把它生成 render,最后运行 render,生成虚拟 DOM 树
  • 挂载完成:页面上显示

在这里插入图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • layui问题之模拟table表格中的选中按钮选中事件的方法

    layui问题之模拟table表格中的选中按钮选中事件的方法

    今天小编就为大家分享一篇layui问题之模拟table表格中的选中按钮选中事件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 微信小程序点击列表跳转到对应详情页过程解析

    微信小程序点击列表跳转到对应详情页过程解析

    这篇文章主要介绍了微信小程序点击列表跳转到对应详情页过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • JavaScript中的class类详解

    JavaScript中的class类详解

    JavaScript 中的类(Class)是一种新的语言特性,它让我们可以使用面向对象编程的思想来更加方便地组织和管理代码。在本文中,我们将详细介绍 JavaScript 中的类特性,感兴趣的同学可以借鉴阅读
    2023-05-05
  • JS判断两个对象内容是否相等的方法示例

    JS判断两个对象内容是否相等的方法示例

    这篇文章主要介绍了JS判断两个对象内容是否相等的方法,结合具体实例形式分析了javascript针对字符串、数组及对象的相关判断技巧,需要的朋友可以参考下
    2017-04-04
  • JavaScript组成、引入、输出、运算符基础知识讲解

    JavaScript组成、引入、输出、运算符基础知识讲解

    JavaScript 被数百万计的网页用来改进设计、验证表单、检测浏览器、创建cookies,以及更多的应用。这篇文章主要介绍了JavaScript组成、引入、输出、运算符基础知识讲解,需要的朋友可以参考下
    2016-12-12
  • 使用p5.js临摹动态图形

    使用p5.js临摹动态图形

    这篇文章主要为大家详细介绍了如何使用p5.js临摹动态图形,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • javascript 不停(setInterval)/延时(setTimeout)函数使用实例

    javascript 不停(setInterval)/延时(setTimeout)函数使用实例

    如果想实现页面的一些函数的定时执行,需要用到下面的函数大家可以看下用法。
    2009-08-08
  • JavaScript实现京东快递单号查询

    JavaScript实现京东快递单号查询

    这篇文章主要为大家详细介绍了JavaScript实现京东快递单号查询,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • JavaScript中 Promise 的使用技巧

    JavaScript中 Promise 的使用技巧

    这篇文章主要介绍了JavaScript中 Promise 的使用技巧,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • JS实现的随机排序功能算法示例

    JS实现的随机排序功能算法示例

    这篇文章主要介绍了JS实现的随机排序功能算法,结合具体实例形式分析了javascript常用的排序算法实现技巧,需要的朋友可以参考下
    2017-06-06

最新评论