前言:有些时候,我们在做了某些回调方法或者说是作了某些修改数据的操作之后,会发现数据在视图上没有立即更新,出现这种情况如何解决,就用到了$nextTick了。

作用:它可以在下次dom更新循环结束之后执行延迟回调,在修改数据之后立即使用该方法,就可以获取更新之后的dom。

实现原理

在 Vue 的文档中,说明了 Vue 是异步执行 dom 更新的。然后异步任务的执行机制,是等所有同步任务执行完之后,浏览器读取任务队列中的异步任务,开始执行。当任务队列中的任务执行完毕之后,算一轮事件循环,这个时候Vue才会进行dom视图更新。

Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。

使用场景

  1. 在vue的生命周期 created() 钩子函数中进行 dom 操作,一定要放在 $nextTick() 函数中执行。在 created() 钩子函数执行的时候 DOM 其实并未进行任何渲染,而此时进行 DOM 操作无异于徒劳,所以此处一定要将 DOM 操作的代码放进 nextTick() 的回调函数中。
  2. 在数据变化后要执行某个操作,而这个操作需要使用随数据改变而改变的 DOM 结构的时候,这个操作都应该放进 Vue.nextTick()的回调函数中。
  3. 获取元素宽度,需要在 DOM 渲染完毕后执行

使用技巧

  • 其实nextTick就是一个异步微函数,执行的时候通过async和await去控制执行的顺序就行了
  • 比如
1
2
3
4
5
6
7
8
9
// 保证滚动条一直在最底部
const scrollContainer: any = ref(null)
// 消息发生改变
watch(() => props.messageInfo, async() => {
// 会先执行nextTick,等待dom数据发生变化
await nextTick();
// 再执行下面的函数
scrollContainer.value.scrollBy(999999, 999999);
});