AlgoInsight

Q&A

How to use the Vue.nextTick() method in Vue

By AlgoInsight Team2026-06-07frontendvuejavascript

Overview

Vue doesn't update the DOM synchronously when you change reactive data. For efficiency, it batches changes and flushes them in a single "tick." So right after mutating state, the DOM still shows the old content. nextTick schedules work for after that flush, when the DOM is current - essential for reading element sizes, focusing newly-rendered inputs, or integrating with non-Vue code.

graph LR
    A[Change reactive data] --> B[Vue queues DOM update]
    B --> C[DOM NOT updated yet this tick]
    C --> D["nextTick(callback)"]
    D --> E[Vue flushes DOM updates]
    E --> F[Callback runs: DOM is now current]
    style D fill:#1e1b4b,color:#fff

The Problem It Solves

// Vue 3 Composition API
import { ref } from "vue";
const message = ref("old");

function update() {
  message.value = "new";
  console.log(document.getElementById("msg").textContent);
  // ⚠ still "old" - the DOM hasn't updated yet this tick
}

The DOM update is queued, not immediate, so reading it right away gives stale content.

Using nextTick (Vue 3)

Import and await it (or pass a callback):

import { ref, nextTick } from "vue";
const message = ref("old");

async function update() {
  message.value = "new";
  await nextTick();                 // wait for the DOM to update
  console.log(document.getElementById("msg").textContent);  // "new" ✓
}

// callback form:
nextTick(() => {
  console.log("DOM updated");
});

Vue 2 Equivalents

this.message = "new";
this.$nextTick(() => {
  // DOM is updated here
});
// or the global: Vue.nextTick(() => { ... })

The concept is identical; only the access path differs (this.$nextTick / Vue.nextTick in Vue 2, the imported nextTick in Vue 3).

Common Use Cases

Focus a newly-rendered element

showInput.value = true;          // v-if reveals an input
await nextTick();                // wait for it to render
inputRef.value.focus();          // now it exists in the DOM

Measure updated layout

items.value.push(newItem);
await nextTick();
const height = listRef.value.scrollHeight;   // accurate post-update size

Scroll to new content

messages.value.push(msg);
await nextTick();
container.value.scrollTop = container.value.scrollHeight;  // scroll to bottom

Why DOM Updates Are Async

Batching is a performance optimization: if you change ten reactive values in one function, Vue updates the DOM once afterward rather than ten times. The trade-off is that the DOM lags your data within the same synchronous block - and nextTick is the official hook to run code after the batch is applied.

Why This Matters in Interviews

Vue interviews use nextTick to test understanding of Vue's reactivity and async DOM updates. Key points: Vue batches DOM updates asynchronously (so the DOM isn't updated immediately after a data change), and nextTick runs code after that flush - used for focusing/measuring/scrolling to freshly-rendered elements. Knowing both the callback and await forms, and the Vue 2 (this.$nextTick) vs Vue 3 (imported nextTick) access, shows version awareness. The "why" - batching for performance - is the conceptual core (and parallels React's useEffect/state-batching).

Common Pitfalls

References

More answers