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

yizhihongxing

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日

相关文章

  • 2019 金三银四:阿里P9架构的Android大厂面试题总结

    2019 金三银四:阿里P9架构的Android大厂面试题总结 一、前言 这篇文章主要总结了阿里P9架构组在2019年金三银四时的Android岗位面试题,是对于Android面试的一份很好的蓝图。在准备Android面试时,可以使用这篇文章中的内容来检验自己的技术水平,也可以根据这些题目进行有针对性的复习和准备。 二、面试题 1. 说一下你对于Androi…

    Vue 2023年5月28日
    00
  • JS实现的类似微信聊天效果示例

    JS实现的类似微信聊天效果示例,可以通过以下步骤来完成: 编写HTML结构 我们可以使用 标签来包裹聊天记录,每条聊天记录用 标签表示,聊天头像使用标签,聊天内容使用 标签表示。 示例代码: <ul id="chat-container"> <li class="chat-right"> &lt…

    Vue 2023年5月28日
    00
  • gojs实现蚂蚁线动画效果

    为了实现蚂蚁线动画效果,可以使用gojs库中的动画和数据模型功能。下面是实现该效果的完整攻略: 创建GoJS图表数据模型 蚂蚁线动画效果需要使用GoJS的Layout模块。在Layout模块的输入上,需要创建一个数据模型,以描述要排列的节点及它们之间的连接关系。数据模型可以由JSON对象创建,包含节点和联系人数组。示例: var data = { nodeD…

    Vue 2023年5月28日
    00
  • React和Vue的props验证示例详解

    关于React和Vue的props验证示例相关的攻略,我可以简要介绍以下内容。 标题 React和Vue的props验证 内容 在React和Vue中,我们可以使用props机制进行组件之间的数据传递,但由于传递的数据经常是不可控的,所以我们需要检查以确保我们接收到我们预期的数据类型和值。这就是所谓的props验证机制,我们可以减少代码块,减少不必要的信息和…

    Vue 2023年5月27日
    00
  • 解决vue单页面应用进入页面加载所有 js 的问题

    解决 Vue 单页面应用进入页面加载所有 js 的问题需要使用到 webpack 的代码分割功能。 Webpack 提供了代码分割功能,通过将应用中的代码分割成多个块(chunk),可以实现按需加载,减少首次加载时间。 以下是详细攻略: 步骤一:配置 webpack 在 webpack.config.js 中进行配置,启用代码分割功能,并将其设置为按需加载。…

    Vue 2023年5月28日
    00
  • vue watch关于对象内的属性监听

    Vue.js 是一款轻量级的MVVM框架,提供了非常方便的API用于响应用户操作,其中watch就是其中非常重要的一部分,用于实现数据的监听,从而对数据的变化做出响应。 当需要监听对象内部属性时,可以使用深度监听,即使用deep:true选项,Vue会递归地监听对象以及对象内的所有属性变化。下面提供两个示例说明。 示例1 在模板中有一个输入框和一个按钮,当按…

    Vue 2023年5月28日
    00
  • Vue组件的渲染流程详细讲解

    请先了解Vue组件渲染的基本流程: 解析模板:Vue会解析组件模板中的所有内容,包括HTML标记、CSS样式和JavaScript交互代码等。 创建VNode:解析完模板后,Vue会根据解析出来的数据创建一个虚拟节点(Virtual Node)。 创建组件实例:根据VNode创建组件实例,Vue会在实例化组件时对其进行一些具体的属性、数据等等进行初始化。 渲…

    Vue 2023年5月28日
    00
  • 为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置

    为nuxt项目写一个面包屑cli工具是一个比较有用的开发工具,它可以自动帮助开发者根据路由配置文件自动生成对应的页面及面包屑配置文件,并且可以简化开发的流程。下面是这个工具的实现过程: 步骤一:创建nuxt插件 我们可以通过在nuxt.config.js中配置plugins选项来创建一个nuxt插件: // nuxt.config.js plugins: […

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