请你阐述一下对vue虚拟dom的理解

简介: 在vue中,每一个组件其实都会被vue编译成一个vNode(虚拟dom),每个组件都有一个render函数,每个render函数都会返回一个虚拟dom树,这也就意味着每个组件都对应一棵虚拟DOM树

面试题:请你阐述一下对vue虚拟dom的理解


1. 什么是虚拟dom?


虚拟dom本质上就是一个普通的JS对象,用于描述视图的界面结构 如下:


{
tag: 'div',
props: {
  id: 'app'
},
chidren: [
  {
    tag: 'p',
    props: {
      className: 'text'
    },
    chidren: [],
    text: 'hello world!!!'
  }
]
}
复制代码


生成的html代码是这样的:


<div id="app">
    <p class="text">hello world!!!</p>
</div>
复制代码


在vue中,每一个组件其实都会被vue编译成一个vNode(虚拟dom),每个组件都有一个render函数,每个render函数都会返回一个虚拟dom树,这也就意味着每个组件都对应一棵虚拟DOM树


6f8bd27546be9598158d5d0568d61c5c.png


2. 为什么需要虚拟dom?


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


这里来做一个简单的测试,创建等量的js对象和等量的dom对象,看看消耗的时间分别是多少。


4bd54a1880cf50c7f1ade755aee70609.png


普通对象,在数组放入10w个对象,消耗时间是 40ms


72ae8da22d1efd6a0dcfbb8e8030011a.png


创建一个普通的dom对象,在数组中放入,消耗的时间是132s;大概是普通对象的4倍


因此,在上述的列子中,从创建对象中可以看出来,创建真实的dom其实是花时间的,这也只是一开始的创建,如果在更新中,频繁的更新真实的dom,还会引起浏览器的重绘和浏览器的重排,使用虚拟dom来替代真实dom,主要为解决渲染效率的问题


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


在一个组件实例首次被渲染时,它先生成虚拟dom树,然后根据虚拟dom树创建真实dom,并把真实dom mount(挂载)到页面中合适的位置,此时,每个虚拟dom便会对应一个真实的dom。


12dc94b12f17acb68c3d853151567464.png


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


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


cdc037fdd086a21214450d62c02bf643.png


通过这里,咋们可以知道,虚拟dom不是一定比真实dom快的,当我们第一次创建的时候,你虚拟dom多生成了一道,而我的真实dom是直接挂载的,然后还有是如果页面结构简单,真实dom也是要比虚拟dom更快的!


4. 模板和虚拟dom的关系


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


编译的过程分两步:


1.将模板字符串转换成为AST

2.将AST转换为render函数


如果使用传统的引入方式,则编译时间发生在组件第一次加载时,这称之为运行时编译。


如果是在vue-cli的默认配置下,编译发生在打包时,这称之为模板预编译。


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


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


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


5. 拓展


在聊到虚拟dom的时候,其实vue也是参考一个虚拟dom库( snabbdom)的更新操作的。


2ac72876ee9928c5e6ef01c88d69443c.png


看到上面的h是不是感觉很熟悉呀,熟悉就行动起来,源码整起来

相关文章
|
4天前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
38 1
|
14天前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
2月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
46 1
vue学习第一章
|
2月前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
32 1
|
2月前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
2月前
|
JavaScript 前端开发 开发者
Vue是如何劫持响应式对象的
Vue是如何劫持响应式对象的
33 1
|
2月前
|
JavaScript 前端开发 API
介绍一下Vue中的响应式原理
介绍一下Vue中的响应式原理
35 1
|
2月前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
|
2月前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
2月前
|
存储 JavaScript 前端开发
介绍一下Vue的核心功能
介绍一下Vue的核心功能

热门文章

最新文章