vue2 虚拟DOM详解

223 阅读4分钟

当听到虚拟DOM,我们一定会想到一些问题,根据这些问题,我们也就可以慢慢了解到虚拟DOM到底是什么东东;

首先第一个问题,什么是虚拟DOM?

什么是虚拟DOM?

  1. 虚拟DOM本质上是一个对象,只是这个对象描述了这个页面视图的结构
// 就像这样,实际上要很复杂
var 虚拟DOM = {
    '左上角':'logo',
    '右上角':'登录和注册按钮',
    '中间':'内容区域',
    '底部':'总结区域'
}
  1. 在vue中每一个组件都有一个属于自己的render函数,每一个render函数,最终都会返回一个虚拟DOM树。
  2. 也就是说,每一个组件都有一个自己的虚拟DOM树,如果这个组件更新了,仅仅需要重新渲染自己的虚拟DOM树就好了。
  3. 下一个问题为什么需要这个虚拟DOM呢?

为什么需要虚拟DOM

  • vue中只要渲染页面就一定会调用render来生成虚拟DOM,这种渲染,不仅仅发生在组件的创建时,也发生在组件视图的更新的时候。

  • 如果每一次更新,都将原来的已经渲染好的组件全部删除掉,在重新渲染,那么不得了了,这个效率和性能的损耗要大到不要不要的,就算,将这个页面上的一个数字1改为了2,那么也要将整个组件全部删掉,重新渲染,那这!!!!!也太。。。了吧。

  • 所以vue使用了虚拟DOM来代替真实的DOM就是为了解决这个效率问题的

  • 那么下一个问题虚拟DOM是如何转换为真实的DOM的呢?

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

  • 在一个组件第一次被渲染的时候
    • 会生成虚拟DOM,然后根据虚拟DOM树,创建真实的DOM树,并把真实的DOM树挂载到页面中属于这个DOM的位置上。
    • 每一个虚拟DOM都会一一对应一个真实的DOM
  • 如果一个组件受响应式数据的影响,需要改变数据,重新渲染的时候
    • 会重新调用这个组件的render函数,来生成一个新虚拟DOM树
    • 将新旧两颗DOM树进行对比,对比时用到的就是大名鼎鼎的diff算法;diff算法会找到最小的需要变动的地方,然后进行更新到需要变动的虚拟DOM节点上
    • 最后去更改真实的DOM,此时,变动就会很小了

看完上面的几个问题,我们发现整个生成真实DOM的过程,主要都是render函数和虚拟DOM来个东西就可以完成了,那我们写是template里面的模板呢,又是怎么回事?那么请看下一个问题

// 这个template里面的模板是怎么回事
<template>
  <div>
      <h1>
          hello world
      </h1>
  </div>
</template>

<script>

</script>

<style>

</style>

模版和虚拟DOM的关系

vue框架中有一个compile模块,这个模块主要负责将模编译换为render函数,调用render函数后就会得到虚拟DOM树了

编译的过程分为两步

  • 将模板转换为AST抽象语法树(用一种js的树型结构来描述js代码)
  • 将AST抽象语法树转换为render函数

编译是一件很耗费性能是事情,vue为了节省性能,会让我们用vue-cli脚手架来搭建项目,这样将整个项目在打包时,就会将模板编译成render函数,这是使用脚手架的原因之一,这个称之为模板预编译

还有一种是传统的通过script标签来引入compile模块,那么引入进来的方式,会在渲染的时候才进行编译,这个称之为运行时编译

预编译可以有效的提高页面的加载和运行速度,而且在运行的时候因为模板已经被编译成render函数了,所以就不需要compile模块了,vue-cli会在打包时,用完后,将该模块不添加到打包结果中,这样有就减少了一定的打包体积。

最后我们发现,模板的存在,仅仅是方便了我们开发人员是书写代码时更加的方便,vue最终的运行时是不需要这个模板的。

完!!

如有不足和错误之处,还请指教。

感谢阅读!!!