What is Vue.js nextTick
January 13, 2021
The DOM in Vue JS is updated asynchronously. When you change a value, the change is not immediately rendered in the DOM. Instead, Vue queues up a DOM update and then updates the DOM. Sometimes you have to manipulate the rendered DOM imediatly after Vue renders it.In these cases you would use nextTick.
We will try to illustrate the role of nextTick in the following example.
Let’s say we have a chat box with incoming and sent messages, and for the sake of simplicity, we will ignore the incoming messages. The goal is to scroll the container immediately after adding a new message.
<template>
<div id="app">
<div ref="box" class="box">
<div v-for="(message, key) in messages" :key="key">{{message.body}}</div>
...
</div>
<button v-on:click="addMessage">Add message</button>
</div>
</template>
<style>
.box {
height: 100px;
width: 300px;
overflow: scroll;
border: 1px solid #000
}
</style>
<script>
export default {
name: "App",
data: () => {
return {
messages: [
{ body: "Message 1" },
{ body: "Message 2" },
{ body: "Message 3" },
{ body: "Message 4" },
{ body: "Message 5" }
]
};
},
methods: {
async addMessage() {
// Add message
this.messages.push({ body: `Message ${this.messages.length+1}`})
// Scroll bottom
this.$refs.box.scrollTop = this.$refs.box.scrollHeight
}
}
};
</script>
Here’s the CodePen:
When you click add messages multiple times, in the first case, the container scrolls down but never reach the bottom.
Now let’s add nextTick and see if it works:
...
async addMessage() {
// Add message
this.messages.push({ body: `Message ${this.messages.length+1}`})
// Wait for DOM to update
await this.$nextTick()
// Scroll bottom
this.$refs.box.scrollTop = this.$refs.box.scrollHeight
}
...
Now if you click on add message, in the second case you will notice that the container scrolls to the bottom.
We can pass a callback function into nextTick instead of using it as a promise like this:
...
async addMessage() {
// Add message
this.messages.push({ body: `Message ${this.messages.length+1}`})
// Wait for DOM to updaten then scroll down
this.$nextTick(() => {
this.$refs.box.scrollTop = this.$refs.box.scrollHeight
})
}
...
This is one of the many examples, like this form submit, where you should use nextTick to watch for the DOM change.