Vue异步更新DOM及$nextTick执行机制解读

Vue异步更新DOM及$nextTick执行机制解读

在 Vue 中,DOM 更新并不是同步执行的,除非使用 this.$nextTick 方法,它可以保证在本次 DOM 更新后执行回调函数,下面我就来详细解读这个机制。

异步更新DOM

Vue 在进行 DOM 更新时,通常借助浏览器的异步更新机制,将多个数据变更合并为一次更新,以提高更新效率。这个机制体现在以下场景:

  1. 生命周期函数的调用是异步执行的,如 createdmounted 等。在这些生命周期函数中,无法直接获取更新后的 DOM 元素,如果需要对 DOM 进行操作,可以使用下面介绍的 $nextTick 方法。

  2. Watcher 监听器的回调函数也是异步执行的。当监听的数据发生变化时,Vue 会判断是否需要触发回调函数,如果需要,它会将回调函数推入一个异步队列中,等到更新结束后再一次性执行所有回调函数。

$nextTick执行机制

在需要对更新后的 DOM 进行操作时,可以使用 $nextTick 方法。该方法接收一个回调函数作为参数,在本次 DOM 更新结束后执行该回调函数。下面介绍该方法的执行机制:

  1. $nextTick 方法会将回调函数推入异步队列,并不会立即执行。

  2. Vue 会在本次 DOM 更新结束后,才会遍历异步队列中的回调函数,依次执行它们。

  3. 如果一个回调函数在异步队列中,Vue 发现它已经存在了,则不会重复添加该函数,也不会执行两次。

下面通过两个示例来说明异步更新和 $nextTick 的机制。

示例一

在以下代码中,组件的一个数据属性 count 被改变时,我们需要得到更新后的 DOM 元素的高度。因为 DOM 更新是异步执行的,所以直接获取元素的高度是不准确的。我们可以在更新后使用 $nextTick 方法获取正确的高度值。

<template>
  <div class="container">
    <div ref="content" :style="{ height: height + 'px' }">
      <p v-for="i in count" :key="i">{{ i }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0,
      height: 0
    };
  },
  methods: {
    handleClick() {
      this.count++;
      this.$nextTick(() => {
        this.height = this.$refs.content.clientHeight;
      });
    }
  },
  mounted() {
    this.height = this.$refs.content.clientHeight;
  }
};
</script>

在组件 mounted 阶段,我们通过 ref 获取容器元素的高度并赋值给 height 属性。在 handleClick 方法中,改变了 count 值后,调用 $nextTick 方法等待 DOM 更新后获取新的高度值。在回调函数中,我们通过 $refs 获取容器元素并获取它的 clientHeight 属性,赋给 height,此时,更新后的高度值已经被正确获取。

示例二

在以下代码中,当用户在搜索框中输入文字时,我们需要更新列表数据项以匹配搜索词,并更新搜索框提示的文字。然而搜索框的内容是双向绑定的,所以在更新列表数据后,需要使用 $nextTick 等待更新后 DOM 元素的渲染,才能更新搜索框提示的文字。

<template>
  <div class="container">
    <input v-model="keyword" @input="handleSearch" />
    <ul>
      <li v-for="item in filteredList" :key="item.id">{{ item.name }}</li>
    </ul>
    <div>{{ message }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      keyword: "",
      list: [
        { id: 1, name: "apple" },
        { id: 2, name: "banana" },
        { id: 3, name: "carrot" }
      ],
      message: ""
    };
  },
  computed: {
    filteredList() {
      return this.list.filter(item =>
        item.name.toLowerCase().includes(this.keyword.toLowerCase())
      );
    }
  },
  methods: {
    handleSearch() {
      this.$nextTick(() => {
        this.message = `共搜索到 ${this.filteredList.length} 个结果`;
      });
    }
  }
};
</script>

在上述示例中,搜索框的值是双向绑定的,当用户在输入框中输入文字时,会触发 handleSearch 方法,在该方法中,我们首先使用 this.$nextTick 方法等待 DOM 的更新,之后使用 computed 属性过滤数据列表,再通过 $nextTick 方法获取更新后的列表项数量,并赋值给 message,完成搜索结果的提示。

至此,Vue 异步更新DOM及 $nextTick 执行机制的解读就讲解完了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue异步更新DOM及$nextTick执行机制解读 - Python技术站

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

相关文章

  • vue 过滤器和自定义指令的使用

    当我们在使用 Vue.js 构建应用程序时,我们有时需要对数据进行格式化或者在 DOM 元素上添加特殊功能。这时,Vue.js 提供了两种方案:过滤器和自定义指令。 Vue 过滤器 过滤器是应用于文本转换的 Vue 函数。它们可以用于一些常见的文本格式化任务,例如通过将字符串转换为大写或小写。 全局过滤器 我们可以使用 Vue.filter() 方法创建一个…

    Vue 2023年5月27日
    00
  • vue实现全选功能

    下面是详细讲解“Vue.js实现全选功能”的完整攻略,包含两条示例说明: 一、实现思路 要实现全选功能,需要以下几个步骤: 定义一个变量来存储当前是否为全选状态。 绑定checkbox的v-model,将每个checkbox的选中状态绑定到一个数组中。 使用计算属性,判断当前是否处于全选状态,然后绑定全选的checkbox的v-model,实现全选功能。 监…

    Vue 2023年5月29日
    00
  • mpvue中使用flyjs全局拦截的实现代码

    mpvue是一个能够基于Vue.js快速开发小程序的框架。与Vue.js类似,mpvue的语法和API几乎与之相同,开发者可以在短时间内熟练掌握其使用。而flyjs是一个优秀的基于Promise的HTTP请求库,能够支持拦截器等高级功能。本文将详细讲解在mpvue中使用flyjs全局拦截的实现代码,以及两个示例说明。 安装和使用flyjs 首先,在mpvue…

    Vue 2023年5月28日
    00
  • vue中push()和splice()的使用解析

    Vue中push()和splice()的使用解析 在Vue中,使用push()和splice()可以对数组进行增删改操作。本篇攻略将对这两个方法进行详细解析,并给出至少两个示例来说明使用这两个方法。 push() 的使用解析 push() 方法可以向数组的末尾添加新的元素,并返回数组的新长度。其语法如下: array.push(item1, item2, .…

    Vue 2023年5月28日
    00
  • 在Vue中是如何封装axios

    在Vue中,axios库通常用于进行网络请求。为了方便代码复用和管理,我们可以将axios进行封装,封装后的axios可以配置全局的拦截器、预设基础路径、统一处理错误响应等。下面是封装axios的完整攻略: 1. 安装axios 在封装axios之前,我们首先需要安装axios库。在项目根目录下打开终端,输入以下命令进行安装: npm install axi…

    Vue 2023年5月28日
    00
  • vue编译器util工具使用方法示例

    对于vue编译器util工具的使用方法,我们可以分为两部分:安装和使用。 安装vue编译器util工具 vue编译器util工具是一个npm包,因此可以使用npm进行安装。在命令行中输入下面命令进行安装: npm install @vue/compiler-util –save 使用vue编译器util工具 在vue模板编译过程中使用vue编译器util工…

    Vue 2023年5月27日
    00
  • Vue中定义全局变量与常量的各种方式详解

    下面将对“Vue中定义全局变量与常量的各种方式详解”的完整攻略进行讲解。 定义全局变量 使用Vue.prototype 我们可以使用Vue.prototype来定义全局变量。具体步骤如下: 在Vue实例化之前,通过Vue.prototype添加需要定义的全局变量 javascript Vue.prototype.$myVariable = ‘这是一个全局变量…

    Vue 2023年5月28日
    00
  • vue-calendar-component 封装多日期选择组件的实例代码

    那么我们开始讲解“vue-calendar-component 封装多日期选择组件的实例代码”的攻略。 1. 简介 vue-calendar-component 是一个基于 Vue 的日历组件,支持单选、范围选择、多选等模式,还支持设置日期限制、自定义样式等功能。它的代码托管在 Github 上,并提供了详细的文档与示例。 2. 安装与使用 通过 npm 安…

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