vue的虚拟DOM使用方式

 更新时间:2024年09月03日 09:22:05   作者:Ocean__Lv  
这篇文章主要介绍了vue的虚拟DOM使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1. vue的虚拟DOM (VNode VDOM)

虚拟DOM就是一个JS对象,用它来描述真实DOM

1.1 为什么 virtual dom 是好用的

demo1: 多次执行dom操作

<body>
    <div style="width: 200px; border:1px solid #000;"></div>
    <script>
        var box = document.querySelector('.box');
        var count = 0;
        console.time('a')
        for (var i = 1; i < 10002; i++) {
            count = i
            box.innerHTML += count
        }
        console.timeEnd('a')
    </script>
</body>

demo2: 只执行一次dom操作

var box = document.querySelector( '.box' ) ;
    var num = “0” 
    console.time( 'b' )
      for ( var i = 1 ; i < 10002 ; i ++ ){
        num += i 
      }
      box.innerHTML = num
    console.timeEnd( 'b' )
  • 比较运行时间:得到结论
  • 越多的真实dom操作,越损耗性能
  • 操作数据要大大的减少性能损耗,提高渲染效率

1.2 更新DOM的三种方案的区别

第一种更新DOM的方案

  • 1、data数据
  • 2、模板
  • 3、数据 + 模板 结合,生成真实的DOM -> 视图
  • 4、data发生了变化
  • 5、数据 + 模板 结合,生成真实的DOM,替换原始的DOM

缺陷:

  • 1、第一次生成了完整的DOM片段
  • 2、第二次生成了完整的DOM片段
  • 3、第二次的DOM替换第一次的DOM,非常耗费性能

第二种更新DOM的方案

  • 1、data数据
  • 2、模板
  • 3、数据 + 模板 结合, 生成真实的DOM -> 视图
  • 4、data发生变化
  • 5、数据 + 模板 结合,生成真实的DOM,并不直接替换原始的DOM
  • 6、新的DOM(DocumentFragment)和原始的DOM做比对,找差异
  • 7、找出变化 (比如input框发生了变化)
  • 8、只用新的DOM中的input元素,替换掉老的DOM中input元素

缺陷:

  • 虽然DOM只是局部替换,但是在比对时候的计算是比较耗费性能的,因此,性能的提升并不明显

第三种使用虚拟DOM的方案

  • 1、读取data数据
  • 2、读取模板
  • 3、数据 + 模板 生成虚拟DOM(虚拟DOM就是一个JS对象,用它来描述真实DOM)(损耗一点性能)
  • 原本准备生成的真实dom:<div id=“abc”><span> hello world </span></div>
  • 虚拟DOM:['div', {id: 'abc‘}, ['span', '', 'hello world']]
  • 4、用虚拟DOM的结构生成真实的DOM -> 视图显示 (用document.createElement可基于虚拟DOM生成真实DOM) 真实DOM:<div id='abc'><span></span></div>
  • 5、当data发生了变化
  • 6、数据 + 模板 生成新的虚拟DOM:['div', {id: 'abc'}, ['span', '', 'hi world11111']]
  • 7、比较原始虚拟DOM和新的虚拟DOM的区别(diff算法),比如找到的区别是span中的内容发生了变化(极大提升了性能)
  • 8、将变化的部分生成真实DOM(用createElement可基于虚拟DOM生成真实DOM)
  • 9、将不同部分渲染在页面(直接操作DOM,改变span中的内容)

虚拟DOM优点:

  • 1、性能提升了      
  • 2、它使得跨端应用得以实现,比如:React Native  (RN)

V(virtual虚拟)DOM的渲染流程、虚拟DOM的原理

  • 1.获取数据
  • 2.根据数据创建VDOM 虚拟DOM就是一个JS对象,用它来描述真实DOM(相当于给对象赋值)
  • 3.根据VDOM渲染生成真实DOM ( 根据createElement(‘DIV’) )
  • 4.当数据发生改变后,又会生成新的VDOM
  • 5.通过 diff 算法 比对 多次生成的 VDOM, 将不同的内容比对出来,然后再进行真实DOM渲染,一样的内容是不会进行渲染的,这就是VDOM 的 ‘就地复用’ | ‘惰性原则’

2. vue中key值的作用

key是虚拟dom对象的标识 在更新时key起着极其重要的作用

2.1 理解key值的作用

当状态数据发生变化时,vue会根据【新数据】生成【新的虚拟dom】

随后vue进行【新的虚拟dom】与【旧的虚拟dom】的diff比较 比较规则如下:

a. 如果旧虚拟dom找到了与新虚拟dom相同的key

  • (1)若旧虚拟dom中内容没变,直接使用之前的真实dom
  • (2)若旧虚拟dom中内容发生了改变,则生成新的真实dom 随后替换掉页面中的真实dom

b. 如果旧虚拟dom未找到与新虚拟dom相同的key 根据数据创建新的真实dom随后渲染到页面

2.2 使用index索引值作为key值

数据:  

[{ id: 1, name: '小李', age: 18 },
{ id: 2, name: '小张', age: 19 }]

初始的虚拟dom

<li key=0>小李------18  <input type="text" /></li>
<li key=1>小张------19  <input type="text" /></li>

更新后的数据

{ id: 3, name: '小王', age: 20 },
{ id: 1, name: '小李', age: 18 },
{ id: 2, name: '小张', age: 19 }

更新数据后的虚拟dom

<li key=0>小王------20  <input type="text" /></li>
<li key=1>小李------18  <input type="text" /></li>
<li key=2>小张------19  <input type="text" /></li>

2.3 使用id索引值作为key值

数据:  

[{ id: 1, name: '小李', age: 18 },
{ id: 2, name: '小张', age: 19 }]

初始的虚拟dom

<li key=1>小李------18 <input type="text" /></li>
<li key=2>小张------19 <input type="text" /></li>

更新后的数据

{ id: 3, name: '小王', age: 20 },
{ id: 1, name: '小李', age: 18 },
{ id: 2, name: '小张', age: 19 }

更新数据后的虚拟dom:   

<li key=3>小王------20 <input type="text" /></li>
<li key=1>小李------18 <input type="text" /></li>
<li key=2>小张------19 <input type="text" /></li>

key的作用主要是为了高效的更新虚拟DOM, 其原理是vue在数据更新过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个更新过程更加高效,减少DOM操作量,提高性能。

另外,若不设置key还可能在列表更新时引发一些隐蔽的bug。

vue中在使用相同标签名元素的过渡(transition组件)切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

3. v-if 和v-for为什么不能用在同一个元素

v-for比v-if优先,即每一次都需要遍历整个数组,影响速度。

<div
    v-for="(fileMsg,index) in fileMsgList"
    :key="fileMsg.id"
    v-if="index < 2"
    >
    <sys-file-layout :fileMsg="fileMsg"></sys-file-layout>
</div>

以上代码,如果有100条数据,虽然显示两条,但需要遍历100次,因为v-for优先

更好的解决方案: 是用computed先获取符合条件的数据,再进行遍历

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue学习笔记之v-if和v-show的区别

    vue学习笔记之v-if和v-show的区别

    本篇文章主要介绍了vue学习笔记之v-if和v-show的区别,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • el-select 点击按钮滚动到选择框顶部的实现代码

    el-select 点击按钮滚动到选择框顶部的实现代码

    本文通过实例代码给大家分享el-select 点击按钮滚动到选择框顶部效果,主要代码是在visibleChange在这个popper里面找到.el-select-dropdown__list,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • Vue中Vue router和axios的封装使用教程

    Vue中Vue router和axios的封装使用教程

    当用户登录后,后台会返回一个token给前端,前端下次进入首页后,会先判断token是否过期,如果过期自动进入登录页面,本文给大家介绍Vue中Vue router和axios的封装使用教程,感兴趣的朋友一起看看吧
    2023-11-11
  • vue单向数据流的深入理解

    vue单向数据流的深入理解

    随着前端的项目的越来越复杂,出现了一堆概念来降低开发的复杂性,单向数据流就是其中一个,下面这篇文章主要给大家介绍了关于vue单向数据流的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • VUE写一个简单的表格实例

    VUE写一个简单的表格实例

    在本篇文章里小编给大家整理的是关于VUE中表格的写法实例以及相关知识点内容,需要的朋友们可以参考下。
    2019-08-08
  • 解决Vue2.0中使用less给元素添加背景图片出现的问题

    解决Vue2.0中使用less给元素添加背景图片出现的问题

    今天小编就为大家分享一篇解决Vue2.0中使用less给元素添加背景图片出现的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • vue父组件点击触发子组件事件的实例讲解

    vue父组件点击触发子组件事件的实例讲解

    下面小编就为大家分享一篇vue父组件点击触发子组件事件的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • 超实用vue中组件间通信的6种方式(最新推荐)

    超实用vue中组件间通信的6种方式(最新推荐)

    组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互进行直接的引用,所以组件间的相互通信是非常重要的,这篇文章主要介绍了vue中组件间通信的6种方式,需要的朋友可以参考下
    2022-11-11
  • Vue仿Bibibili首页的问题

    Vue仿Bibibili首页的问题

    这篇文章主要介绍了Vue仿Bibibili首页,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • vue如何从后台获取数据生成动态菜单列表

    vue如何从后台获取数据生成动态菜单列表

    这篇文章主要介绍了vue如何从后台获取数据生成动态菜单列表,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04

最新评论