Vue.js 2.0窥探之Virtual DOM到底是什么?

yizhihongxing

Vue.js 2.0窥探之Virtual DOM到底是什么

什么是Virtual DOM

在现代 Web 应用程序开发中,通常会使用 JavaScript 来动态地创建、操作和更新 HTML 页面元素。然而,这种操作不够有效率,需要对整个 DOM 结构进行重新渲染处理,而且更改频繁时还可能导致页面的卡顿甚至崩溃。

为了解决这个问题,Facebook的工程师在2013年推出了 Virtual DOM 技术,它是一种将虚拟的 DOM 与实际的 DOM 结构进行比较的技术。将需要更新的内容映射到虚拟 DOM 中,虚拟 DOM 会保存所有节点的信息以及它们的层次结构,并根据这些信息生成一棵完整的DOM树。每次更新时,虚拟 DOM 会首先以最小的代价计算出需要修改的地方,然后再将这些修改应用到实际的 DOM 结构中,最终渲染页面。

Vue.js 中也有类似实现,它基于 Virtual DOM 技术将更新操作减少到最小的代价并且提高了应用程序的性能。Vue.js 的 Virtual DOM 对比曾经显示,更新性能比原生 DOM 快上许多倍,并且减少了无法避免的 bug 和异常情况。

为什么需要Virtual DOM

在 HTML 网页中,浏览器将生成一个 DOM 树来表示 HTML 页面的结构。但是,因为浏览器的设计,DOM 树很容易被 JavaScript 操作,比如常见的$$('div')获取所有 div 节点,及之后的操作。但是,虽然 JavaScript 直接操作 DOM 节点的确很方便,却容易造成大量的浪费。

举个例子,当我们需要更新一个 DOM 节点时,通常是重新生成整颗 DOM 树,再将这个节点插入到正确的位置,并删除之前的节点。这样做是非常低效的,特别是当需要大量频繁的更新时,每次都要进行繁琐而低效的 DOM 渲染,会占用大量的 CPU 时间。

因此,Virtual DOM 即通过 JavaScript 的方式,实现 DOM 结构的抽象,减少 DOM 渲染的数量和频率,提高性能。Virtual DOM 是一个轻量级的完整的JavaScript对象结构,它包含了每一个文本,DOM节点和属性,并且能够表达完整的HTML文档。在 Vue.js 编程中,Virtual DOM 是神器,所以允许我们进行快捷、便利的模板渲染和组件结构操作。

Virtual DOM 的优势

  • 大大提高了性能:利用快速的比较算法,在 Virtual DOM 中构建任意的数多点的数据结构进行渲染,可以大大减少在真实 DOM 中的操作。浏览器纯粹靠 CPU 操作是太慢的,所以使用虚拟DOM可以使UI的渲染更加流畅并且效率更高。
  • 避免直接操作DOM带来的风险:DOM的操作显然比数据的操作的代价要高,并且也容易出错。使用虚拟 DOM 实现,会把逻辑和渲染轻量化很多倍,简化代码的编写和移动操作。
  • 个性化操作:虚拟DOM的自主和多样性,可以通过编写模板方法,自己的控件从而实现个性化的操作,比如高级筛选框,动画效果等。

Virtual DOM 的适用场景

虚拟 DOM 并不是一种适合所有情况的解决方案,它有以下两个适用场景:

  • 大型单页应用程序:当应用程序的结构变得越来越庞大时,虚拟 DOM 可以在大型单页应用程序中便于管理和维护。
  • 多个子级组件的应用程序:Vue 虚拟 DOM 使用了相同的 DOM 树结构,这意味着子组件与父级组件共享相同的 DOM 树,这会提高性能并减少代码的重复性。

Vue.js中的Virtual DOM应用

在Vue.js为我们提供的框架中,Virtual DOM被用作了核心部件,具体步骤是:

  1. 将模版编译为.Render function,输出 Virtual DOM。
  2. 执行.Render function,生成 Virtual DOM 对象。
  3. 通过.Reconciliation 算法,找到新旧对比,把需要更新的 Virtual DOM 进行更改。
  4. 通过 new DOM()生成新的DOM,并与旧的DOM比较,找到需要修改的DOM。
  5. 判断修改来进行不同的操作,形成差异。
  6. 只将差异的部分更新到真实的DOM的渲染里面,达到优化的目的。

这样,在数据发生变化的时,组件先在 Virtual DOM 上更新,然后 Virtual DOM 在与真实 DOM 进行比较,只更新发生变化的部分,避免了整体重新渲染的问题。从而提升应用的性能。

示例1:使用 Vue.js 的Virtual DOM 排序动画效果

<template>
  <div>
    <h3>选手表</h3>
    <button @click="sortRacers">排序</button>
    <ul>
      <li v-for="(racer, index) in racers" :key="racer.name" :style="{animationDelay: index * 100 + 'ms'}">
        {{ racer.name }} : {{racer.mph}} mph
      </li>
    </ul>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        racers: [
          { name: 'Tina', mph: 300 },
          { name: 'John', mph: 200 },
          { name: 'Jared', mph: 500 },
          { name: 'Chris', mph: 350 },
          { name: 'Steve', mph: 150 }
        ]
      }
    },
    methods: {
      sortRacers() {
        this.racers = this.racers.sort((a, b) => a.mph < b.mph ? 1 : -1)
      }
    }
  }
</script>

在上面的示例中,每个列表的选手会在输入顺序后以相应速度移动到相应位置。这是通过设置CSS动画来完成的,设置每个列表项的animation-delay属性,用于创建逐渐增加的延迟效果。此处用Virtual DOM 和 Vue.js实现动画效果是理所当然。

示例2:使用Virtual DOM 和Vue.js 实现轮播图

<template>
  <div>
    <transition-group tag="ul" name="slide">
      <li v-for="image in images" :key="image.id">
        <img :src="image.url" alt="轮播图">
      </li>
    </transition-group>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        currentIndex: 0,
        images: [
          { id: 1, url: 'https://picsum.photos/500/300?image=1' },
          { id: 2, url: 'https://picsum.photos/500/300?image=2' },
          { id: 3, url: 'https://picsum.photos/500/300?image=3' },
          { id: 4, url: 'https://picsum.photos/500/300?image=4' },
        ]
      }
    },
    mounted() {
      this.startPlay()
    },
    methods: {
      startPlay() {
        setInterval(() => {
          this.currentIndex++
          if (this.currentIndex >= this.images.length) {
            this.currentIndex = 0
          }
        }, 1000)
      }
    }
  }
</script>
<style scoped>
  .slide-enter-active, .slide-leave-active {
    transition: all .5s ease;
  }
  .slide-enter, .slide-leave-to {
    opacity: 0;
    transform: scale(1.1);
  }
</style>

此处利用了Vue.js 的Transition 功能,来简便的制定轮播图动画效果。利用Virtual DOM,Vue.js 能够自动捕获实际 DOM 中的变化以及导致它们的数据改变,来完成轮播图实际整体的转换。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue.js 2.0窥探之Virtual DOM到底是什么? - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • vue3如何实现挂载并使用axios

    当我们使用Vue3框架开发应用程序时,我们需要使用Axios实现数据通信。在Vue3中,Axios是一个可以在后台执行请求的JavaScript库。在本篇攻略中,我们将会介绍如何在Vue3中挂载及使用Axios。以下分为以下五个步骤: 安装Axios 在Vue3中使用Axios需要安装Axios。你可以通过npm或者yarn进行安装Axios: npm in…

    Vue 2023年5月28日
    00
  • vue+moment实现倒计时效果

    实现倒计时效果是前端项目中常见的需求。本文将介绍如何使用vue和moment.js库实现倒计时效果,并提供两个示例进行说明。 步骤一:安装moment.js库 在使用moment.js库之前,我们需要先进行安装。具体步骤如下: npm install moment –save 这样就可以在vue项目中使用moment.js库了。 步骤二:在vue组件中引入…

    Vue 2023年5月29日
    00
  • vue单个组件实现无限层级多选菜单功能

    下面我将详细讲解“vue单个组件实现无限层级多选菜单功能”的完整攻略。 目录 前置知识 实现步骤 创建Menu.vue组件 编写Menu.vue组件模板 编写Menu.vue组件脚本 在App.vue中使用Menu.vue组件 示例说明 示例1:只有两级菜单 示例2:有三级菜单 前置知识 熟练掌握Vue.js框架的使用 对Vue组件的概念有基本了解 实现步骤…

    Vue 2023年5月27日
    00
  • 解决Vue大括号字符换行踩的坑

    当我们在Vue模板中使用大括号{{}}输出变量或表达式时,由于内容长度过长,可能会导致字符串在大括号内换行,造成渲染效果异常。在此,需要介绍一些技巧和解决方法,帮助解决这个问题。 解决方法:使用v-pre指令 v-pre指令可以让Vue忽略当前标签中的模板语法,直接输出其中的内容。应用v-pre指令后,大括号内的字符将不再进行转义,也就不会出现意料之外的换行…

    Vue 2023年5月27日
    00
  • vue使用axios上传文件(FormData)的方法

    下面是详细的Vue使用axios上传文件(FormData)的方法攻略: 1. 安装axios库 首先需要在Vue项目中安装axios库,可以通过npm命令进行安装: npm install axios –save 2. 引入axios库 在Vue的组件中引入axios库的方法如下: import axios from ‘axios’ 3. 创建FormD…

    Vue 2023年5月28日
    00
  • Uniapp全局消息提示以及其组件的实现方法

    Uniapp是一个跨端开发框架,使得我们可以非常方便地开发和部署多种移动端应用。在开发移动应用时,全局消息提示是一个必不可少的功能,这可以让用户在操作后接收到系统的反馈以便更好地交互。 Uniapp提供了一个uni.showToast()的API方法,可以让我们在全局范围内显示消息提示。下面是如何使用该API的方法: uni.showToast({ titl…

    Vue 2023年5月28日
    00
  • vue.js指令v-for使用及索引获取

    我来给你详细讲解一下 “vue.js 指令 v-for 使用及索引获取” 的完整攻略。 一、vue.js 指令 v-for 的基本用法 在 Vue.js 中,可以使用 v-for 指令来遍历数据,它的基本语法如下: <div v-for="(item, index) in list"> {{ index }}. {{ item…

    Vue 2023年5月29日
    00
  • Vue项目优化打包之前端必备加分项

    针对“Vue项目优化打包之前端必备加分项”的完整攻略,我分别从以下三个方面进行详细的讲解: 代码规范化和优化 webpack的性能调优 最佳实践 代码规范化和优化 代码规范:在Vue开发中,代码规范可以通过使用ESLint和Prettier等工具进行检查和格式化,以确保代码的可读性和可维护性。此外,可以使用Husky和Lint-staged等工具,将代码规范…

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部