你绝对看的懂的Vue虚拟dom

923 阅读3分钟

1. 什么是虚拟dom?

虚拟dom本质上就是一个普通的js对象,用于描述视图的页面结构。 在Vue中,每一个组件都有一个render函数,每一个render函数都会返回一个虚拟dom树,这也就意味着每一个组件中都对应一颗虚拟dom树

image.png

  • 我们可以在组件中打印一个vue实例

image.png

image.png

  1. 通过render函数创建一个虚拟dom

image.png

2. 为什么需要虚拟dom?

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

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

  • 我们可以看一个简单地例子,对比真实的dom对象和 普通对象所渲染出来的时间。 由此可见dom对象耗费的时间是很长的。

image.png

3. 虚拟dom是如何转化为真实的dom?

在一个组件实例被首次渲染的时候,他首先生成一个虚拟DOM树,然后根据虚拟dom树创建真实的dom树,并把真实的dom树渲染到页面中,此时每一个虚拟dom便会对应一个真实的dom。

如果一个组件收到响应式的数据变化时,他仍然会重新调用render函数,创建一个新的虚拟dom,新树和旧树对比,通过对比,vue会找到最小更新量,然后更新必要的虚拟节点,最后,这些更新过的虚拟节点会去修改他们对应的真实dom。这样一来就保证了真实dom达到最小的改动。

4.模板和虚拟dom的关系

vue框架中有一个compile模块,它主要负责将模板转化为render函数,而render函数调用后将会得到虚拟dom。 编译的过程分为两步:

  1. 将模板字符串转化为AST
  2. 将AST转化为render函数。 如果使用传统的引入方式,则编译时间发生在组件的第一次加载中,这称之为运行时编译。 如果在vue-cli的默认配置下,编译发生在打包时,这称之为魔板预编译。 编译是一个及其耗费性能的操作,预编译会有效提高运行时的性能,而且,由于运行时不需要编译,vue-cli打包的时候会排除掉vue中的compile模块,以减少打包体积。 模板的存在,仅仅是为了让开发人员更加方便的书写页面代码。

Vue在最终运行的时候,最终运行的是render函数,而不是模板,因此,模板中的各种语法,在虚拟dom中都是不存在的,他们都会变为虚拟dom的配置。