Vue中的this.$nextTick的使用场景

在 Vue 中,当 data 数据发生改变时,Vue 会自动触发重新渲染视图的过程。但是,有时候我们会发现data数据改变了,但真实 DOM 并没有及时更新。为什么?

 Vue 官方文档对其的定义:

 我们可以理解成, Vue 在更新 DOM 时是异步执行的。

正是这样,因为 Vue 的响应式系统采用了异步更新队列的机制,当我们修改 data 中的数据后, Vue 并不会立即更新真实 DOM ,而是把这个更新操作放入一个队列,其他数据的变化操作也放入这个队列,视图需要等到队列中所有数据变化完成之后,统一进行批量更新

在大多数情况下,Vue会自动在数据变化时执行 DOM 更新,因此很少需要手动使用 $nextTick() 方法。但是,在一些特定场景下,如果需要确保在 DOM 更新后执行某些操作, $nextTick() 方法是非常有用的。

那么它的使用场景是什么呢?

1、若需要在组件中修改 data 数据之后,立即操作更新后的 DOM 元素 使用 $refs 获取到 DOM 元素

<template>
  <div>
    <div class="hello">
      <p ref="g_name">
        当前姓名:<b>{{ name }}</b>
      </p>
      <p class="sex">{{ sex }}</p>
      <button @click="changeName">改变名称</button>
      <button @click="changeSex">改变性别</button>
    </div>
  </div>
</template>

<script>
export default {
  name: "DemoPages",
  data() {
    return {
      name: "张三",
      sex: '男'
    };
  },
  methods: {
    changeName() {
      this.name = "李四";

      //建议以箭头函数的形式传入回调函数,this自动绑定外层作用域的 this(当前组件实例),不会受到其他因素的影响。
      this.$nextTick(() => {
        console.log(this.$refs["g_name"].innerHTML); // 当前姓名:<b>李四</b>
      })
    },
    changeSex() {
      this.sex = '女';

      this.$nextTick(() => {
        const element = document.querySelector('.sex');
        console.log(element.innerHTML);// 女
        //操作更新后的DOM的内容
        //...
      })
    }
  }
};
</script>
<style scoped>
</style>

上述代码中的 changeName 方法中若不用 nextTick ,则拿到的真实 DOM 节点的打印还是

当前姓名:<b>张三</b>

如果你需要在 this.$nextTick 中获取回调函数的返回值,你可以使用 Promise 进行封装。

//如果需要在$nextTick()中获取回调函数的返回值,你可以使用Promise进行封装
      const promise = new Promise((resolve) => {
        this.$nextTick(() => {

          // 在DOM更新后执行的操作
          console.log("DOM已更新");

          // 获取更新后的DOM元素
          console.log(this.$refs["g_name"].innerHTML); // 当前姓名:<b>李四</b>

          // 返回结果
          resolve(this.name)
        })
      })

      promise.then((result) => {
        console.log("回调函数的返回值为:", result) // 当前姓名:<b>李四</b>
      })

需要注意的是,需要在 created 和 mounted 里需要操作渲染后的视图,也最好将处理内容传入 nextTick 的回调函数(callback)中

在 created 钩子函数中,组件实例已经创建完成,但是 DOM 还未渲染,因此在这个阶段进行一些需要操作 DOM 元素的操作,可能无法获取到正确的结果。例如,如果需要获取某个 DOM 元素的尺寸或者修改样式,由于 DOM 还未渲染,无法获取到正确的值或者修改无效。

在 mounted 钩子函数中,组件已经被挂载到 DOM 上,此时可以获取到正确的 DOM 元素并进行操作。然而,由于 Vue 会在 mounted 钩子函数中进行异步的 DOM 更新操作,这些操作是由 Vue 引擎处理的,无法立即得到结果。因此,如果在 mounted 钩子函数中直接进行 DOM 操作,可能会存在一定的延迟。

综上所述, this.$nextTick 方法在  created 和 mounted 钩子函数中的使用,主要是为了在正确的时机进行 DOM 操作,避免可能出现的延迟或无效操作。

2、在更新后执行其他异步操作:当需要在更新后执行其他异步操作时,需要将这些操作放在 this.$nextTick 的回调函数中。例如,发送网络请求、操作浏览器缓存等

// 发送网络请求
this.$nextTick(() => {
  axios.get('/api/data').then(res => {
    console.log(res.data);
  });
});

// 操作浏览器缓存
this.$nextTick(() => {
  localStorage.setItem('myData', 'Hello, World!');
});

Ps:Vue.nextTick 是全局方法,可以在任何地方直接调用;this.$nextTick 是 Vue 实例的方法,它是通过 Vue 的原型链绑定到每个 Vue 实例上的,可以在 Vue 组件中使用。

       两者的作用和使用方式完全一样,都是用于在下次 DOM 更新循环结束后执行回调函数。它们的使用场景和效果也是一样的。

       但是在 Vue3 中, Vue.nextTick 方法已经被废弃,推荐使用 this.$nextTick 方法。在Vue2中, nextTick 方法仍然可用,但建议使用 this.$nextTick 以保持一致性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值