Vue 中 $nextTick() 的應用


Vue 在更新 DOM 時是異步執行的。

只要偵聽到數據變化,Vue 將開啟一個隊列,並緩沖在同一事件循環中發生的所有數據變更。如果同一個 watcher 被多次觸發,只會被推入到隊列中一次。這種在緩沖時去除重復數據對於避免不必要的計算和 DOM 操作是非常重要的。

異步更新DOM實例

<!DOCTYPE html>
<html> 
<head>
    <meta charset="utf-8">
    <title>Vue nextTick</title>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>

<body>
    <div id="app">
        <example></example>
    </div>

    <script>
        // 注冊 example 組件
        Vue.component('example', {
            template: '<span ref="box" @click="updateMessage">{{ message }}</span>',
            data () {
                return {
                    message: '未更新'
                }
            },
            methods: {
                updateMessage () {
                    this.message = '已更新'
                    
                    console.log('nextTick方法前--->', this.$refs.box.textContent) // => '未更新'

                    this.$nextTick(function () {
                        console.log('nextTick方法內--->', this.$refs.box.textContent) // => '已更新'
                    })

                    console.log('nextTick方法后--->', this.$refs.box.textContent) // => '未更新'
                }
            }
        })

        // 創建根實例
        new Vue({
            el: '#app'
        })
    </script>
</body>

</html>

點擊 span , 執行 updateMessage方法,輸出結果如下:

nextTick方法前---> 未更新
nextTick方法后---> 未更新
nextTick方法內---> 已更新

可見,Vue 數據發生變化之后,視圖不會立即變化。該更新過程是異步的。

所以,如果要獲取更新后的視圖,可以使用 $nextTick(callback)。這里的回調函數(callback)將在數據更新完成,視圖更新完畢之后被調用。

$nextTick 結合 async/await 語法

$nextTick() 返回一個 Promise 對象,所以可以使用新的 ES2016 async/await 語法完成相同的事情:

methods: {
    async updateMessage () {
        this.message = '已更新'
        console.log('nextTick方法前--->', this.$refs.box.textContent) // => '未更新'

        await this.$nextTick(function () {
            console.log('nextTick方法內--->', this.$refs.box.textContent) // => '已更新'
        })

        console.log('nextTick方法后--->', this.$refs.box.textContent) // => '已更新'
    }
}

執行點擊事件,打印結果:

nextTick方法前---> 未更新
nextTick方法內---> 已更新
nextTick方法后---> 已更新

$nextTick 常用場景

在Vue生命周期鈎子函數created()中進行的DOM操作。

由於created()鈎子函數中還未對DOM進行任何渲染,所以無法直接操作,需要通過$nextTick()回調來完成。

created() {
    console.log(this.$refs.box.textContent);  // TypeError: Cannot read property 'textContent' of undefined
    this.$nextTick(() => {
        console.log(this.$refs.box.textContent);  // 未更新
    })
},


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM