当听到虚拟DOM,我们一定会想到一些问题,根据这些问题,我们也就可以慢慢了解到虚拟DOM到底是什么东东;
首先第一个问题,什么是虚拟DOM?
什么是虚拟DOM?
- 虚拟DOM本质上是一个对象,只是这个对象描述了这个页面视图的结构
// 就像这样,实际上要很复杂
var 虚拟DOM = {
'左上角':'logo',
'右上角':'登录和注册按钮',
'中间':'内容区域',
'底部':'总结区域'
}
- 在vue中每一个组件都有一个属于自己的render函数,每一个render函数,最终都会返回一个虚拟DOM树。
- 也就是说,每一个组件都有一个自己的虚拟DOM树,如果这个组件更新了,仅仅需要重新渲染自己的虚拟DOM树就好了。
- 下一个问题为什么需要这个虚拟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最终的运行时是不需要这个模板的。
完!!
如有不足和错误之处,还请指教。
感谢阅读!!!