Understanding Vue.js nextTick: Mechanism, Usage, and Custom Implementation

This article explains the Vue.js nextTick API, why scrolling to newly added list items may stop prematurely, demonstrates proper usage with scrollIntoView, and provides a hand‑written implementation using MutationObserver to ensure DOM updates complete before executing callbacks.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Understanding Vue.js nextTick: Mechanism, Usage, and Custom Implementation

Introduction – nextTick is a frequently asked interview topic in Vue.js because it reveals important rendering mechanics; many developers struggle to grasp its execution flow.

Problem scenario – A page initially displays 20 li elements. Clicking a button adds 10 more li items and attempts to scroll the last new element into view with element.scrollIntoView({ behavior: 'smooth' }). The scroll stops halfway because the DOM has not finished updating.

Initial code (incorrect approach)

<template>
    <div>
        <button @click="updateList">更新列表</button>
        <ul>
            <li v-for="n in list">{{ n }}</li>
        </ul>
    </div>
</template>

<script setup>
import { ref } from 'vue';

const list = ref(new Array(20).fill(0))
const updateList = () => {
    // push elements one by one
    list.value.push(...(new Array(10).fill(1)))
    const liItem = document.querySelector('li:last-child')
    liItem.scrollIntoView({ behavior: 'smooth' })
}
</script>

<style lang="css" scoped>
li{
    height: 100px;
    background-color: #21e07a;
    margin: 10px;
}
</style>

Why it fails – Vue’s component lifecycle runs the click handler before the DOM reflects the newly added li elements. The call to document.querySelector('li:last-child') may retrieve an element that hasn’t been rendered yet, causing the scroll to stop.

Solution with nextTick – By deferring the scroll logic until after Vue finishes updating the DOM, the operation works reliably.

Correct code using nextTick

<script setup>
import { nextTick, ref } from 'vue';

const list = ref(new Array(20).fill(0))
const updateList = () => {
    list.value.push(...(new Array(10).fill(1)))
    nextTick(() => {
        const liItem = document.querySelector('li:last-child')
        liItem.scrollIntoView({ behavior: 'smooth' })
    })
}
</script>

The page now scrolls smoothly to the newly added last item.

Hand‑written nextTick implementation

function myNextTick(fn) {
    let app = document.getElementById('app')
    // Observe DOM changes
    var observerOptions = {
        childList: true, // added/removed child nodes
        attributes: true, // attribute changes
        subtree: true   // monitor descendants
    };
    // Create a MutationObserver that calls fn when the DOM update finishes
    let observer = new MutationObserver((el, obs) => {
        fn()
    })
    observer.observe(app, observerOptions)
}

This custom myNextTick uses the native MutationObserver to watch for DOM mutations on the element with id app. When the observed changes match the specified options, the callback runs, ensuring the supplied function executes only after the DOM has been updated.

Conclusion – Using Vue’s built‑in nextTick (or a hand‑rolled version based on MutationObserver) guarantees that DOM‑dependent logic runs at the correct moment, preventing issues like incomplete scrolling.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendJavaScriptMutationObserverVue.jsDOMnextTick
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.