如何在 Vue 中使用 nextTick()

324 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

在Vue使用组件时,对于组件数据的更改不会立即反应在DOM中,因为Vue是异步更新DOM的。

所以需要使用nextTick()或者$nextTick()函数来更新DOM。

Vue.nextTick()

Vue.nextTick()的主要用法是在下次DOM更新循环结束之后执行延迟回调。所以在修改数据之后立即使用这个方法,可以获取更新后的Dom。

// 修改数据
vm.msg = 'Hello'
// DOM 还没有更新
Vue.nextTick(function () {
  // DOM 更新了
})

// 作为一个 Promise 使用
Vue.nextTick()
  .then(function () {
    // DOM 更新了
})

详细使用示例:下面是一个切换元素显示的组件。

<template>
  <div>
    <button @click="handleClick">点击按钮</button>
    <div v-if="show" ref="content">I am an element</div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      show: true,
    };
  },
  methods: {
    handleClick() {
      this.show = !this.show;
      console.log(this.show, this.$refs.content);
    },
  },
};
</script>

点击‘点击按钮’会更改this.show数据,从而控制

元素的显示。

在handleClick处理程序内部,this.show记录到控制台的值与记录到控制台的引用不对应。这意味着 DOM 与组件的数据不同步。

如果想捕捉 DOM 刚刚更新的那一刻,就需要使用函数Vue.nextTick(callback)。在新数据更新到达 DOM 后立即执行。

<template>
  <div>
    <button @click="handleClick">点击按钮</button>
    <div v-if="show" ref="content">I am an element</div>
  </div>
</template>
<script>
import Vue from "vue";
export default {
  data() {
    return {
      show: true,
    };
  },
  methods: {
    handleClick() {
      this.show = !this.show;
      Vue.nextTick(() => {
        console.log(this.show, this.$refs.content);
      });
    },
  },
};
</script>

如上所示,在点击‘点击按钮’时,可以看到this.$refs.content(包含该

元素的引用)是undefined或包含一个元素——与this.show值完全对应。

this.$nextTick()

this.$nextTick()是将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法Vue.nextTick一样,不同的是回调的this自动绑定到调用它的实例上。

new Vue({
  // ...
  methods: {
    // ...
    example: function () {
      // 修改数据
      this.message = 'changed'
      // DOM 还没有更新
      this.$nextTick(function () {
        // DOM 现在更新了
        // `this` 绑定到当前实例
        this.doSomethingElse()
      })
    }
  }
})

还是上面的示例代码,当handleClick()方法中更改this.show数据,立即执行this.$nextTick()以捕捉此更新到达 DOM 的时刻。

<template>
  <div>
    <button @click="handleClick">点击按钮</button>
    <div v-if="show" ref="content">I am an element</div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      show: true,
    };
  },
  methods: {
    handleClick() {
      this.show = !this.show;
      this.$nextTick(() => {
        console.log(this.show, this.$refs.content);
      });
    },
  },
};
</script>

总结

更改组件的数据时,Vue 会异步更新 DOM。

如果想在组件的数据发生变化后捕捉到 DOM 更新的时刻,需要使用Vue.nextTick(callback)orthis.$nextTick(callback)函数。

它们的单个callback参数将在 DOM 更新后立即调用:并且获得与组件数据同步的最新 DOM。

如果不向Vue.nextTick()或者this.$nextTick()提供回调参数,将返回一个promise,这个promise将在 DOM 更新时被解析。