Vue学习-vue中的虚拟dom
一、什么是虚拟dom?
虚拟dom 其实就是一个普通的JavaScript对象,用来描叙试图上有哪些界面结构,并不生成界面,我们可以在生命周期【mounted阶段】打印this._vnode,如下:
它描叙了该阶段是div,有 哪些子节点,哪些属性,它是采用一个js对象来描叙这些,但是它并不会显示在页面上。
在vue中,每一个组件都有一个render函数,这个函数会生成一个虚拟dom,这就意味着每一个组件都对应一个虚拟dom树。
二、为什么需要虚拟dom?
这个主要是由vue结构所决定的,在vue中,渲染试图会调用render函数,不仅在创建视图的时候被调用,当组件所依赖的数据或者属性发生了改变的时候,也会调用render函数,如果是使用真实的dom,当创建,修改,删除,插入dom的话是非常消耗性能的,如下所示,当修改一个js对象远比操作真实的dom要有效率的多。
<script> var times = 10000000;//次数为1000万次 //js对象 console.time(`js object`); for (var i = 0; i < times; i++) { var obj = {}; } console.timeEnd("js object"); //真实dom对象 console.time(`dom object`); for (var i = 0; i < times; i++) { var obj = document.createElement("div"); } console.timeEnd("dom object"); </script> 「运行结果」:
运行结果:
三、虚拟dom是如何转换为真实dom的?
在组件渲染的时候会调用render函数,这个函数会生成一个虚拟的dom,再根据这个虚拟的dom来生成真实的dom,然后将这个真实的dom给挂载到页面的合适的部位,总的来说创建真实的dom是必不可少的一部分,如果视图只需要渲染一次,后续数据的改变不会影响到视图的改变,vue的效率其实要比真实操作dom的效率要低,因为vue还要创建一个虚拟的dom,但是如果组件内有响应式的数据,当数据发生改变的时候,就会调用render 函数来生成一个新的虚拟dom树,将新的虚拟dom树和旧的虚拟dom树进行对比,然后找到必须修改的虚拟dom,最后根据修改的虚拟dom,来修改真实的dom,这样就保证了对真实的dom操作达到最小的改变,
在进行新的虚拟dom和旧的虚拟dom对比的算法是patch算法,它会找到新的虚拟dom树和旧的虚拟dom树之间的差别。
四、模板和虚拟dom的关系?
在vue中有一个compile模块,这个模块将template字符串编译成render函数,render函数最后返回一个虚拟dom。
编译过程分为两步:
(1)将template 转换为AST(抽象语法树)
(2)将AST转换为render函数
* 使用<script>标签来引入vue 的,编译是发生在组件第一次加载的时候,这种称为 运行时编译
* 第二种是使用 vue-cil 框架生成的 vue 项目,这种是在打包的时候就进行了编译,称为 模板预编译
编译
是一个极其耗费性能的操作,预编译可以有效的提高运行时的性能,而且,由于运行时已经不需要编译,vue-cli在打包时会排除掉vue中的compile模块,这样可以减少打包体积。
模板的存在,仅仅只是为了我们更加方便的书写界面代码,vue最终运行的时候,最终需要的是render函数,而不是模板,这里要注意的是vue它是不认识模板的,模板是vue-cli预编译所需要的,它最终会将模板编译成render函数提供给vue正常运行。因此模板中的各种语法,在虚拟dom中都是不存在的,它们都会变成虚拟dom的配置。
转自:https://mp.weixin.qq.com/s/g7wQXjXeFNxtLzGS1uM6uA