Vue.nextTick()理解

李赫feixuan發表於2018-08-08

什麼是Vue.nextTick()

官方解釋:在下次 DOM 更新迴圈結束之後執行延遲迴調。在修改資料之後立即使用這個方法,獲取更新後的 DOM。

注意:重點是獲取更新後的DOM 就是在開發過程中有個需求是需要在created階段運算元據更新後的節點 這時候就需要用到Vue.nextTick()

原因

created()鉤子函式執行的時候DOM 其實並未進行任何渲染,而此時進行DOM操作無異於徒勞,所以在created中一定要將DOM操作的js程式碼放進Vue.nextTick()的回撥函式中。與之對應的就是mounted()鉤子函式,因為該鉤子函式執行時所有的DOM掛載和渲染都已完成,此時在該鉤子函式中進行任何DOM操作都不會有問題 。

案例一

<template>
    <div id="app">
        <div ref="msgDiv">{{msg1}}</div>
        <br/>
        <div>{{msg2}}</div>
        <br/><br/>
        <button @click="changeMsg">點選我</button>
    </div>
</template>
<script>
    export default {
        name: 'App',
        data(){
          return {
            msg1: "你我貸",
            msg2: "理財"
          }
        },     
        methods: {
            changeMsg() {
                this.msg1 = "飛旋"
                this.msg2 = this.$refs.msgDiv.textContent;
                console.log(this.$refs.msgDiv.textContent)
                this.$nextTick(function(){
                    console.log(this.$refs.msgDiv.textContent)
                })
            }
        }
    }
</script>複製程式碼

觸發前:

Vue.nextTick()理解

觸發後:


Vue.nextTick()理解


案例二

<template>
    <div id="app">
        <div ref="msgDiv" id="msgDiv" v-if="showDiv">{{msg1}}</div>
        <button @click="changeMsg">點選我</button>
    </div>
</template>

<script>
    export default {
        name: 'App',
        data(){
          return {
            msg1: "你我貸",
            showDiv: false
          }
        }, 
        methods: {
            changeMsg() {
                this.showDiv = true
                console.log(document.getElementById("msgDiv"))
                this.$nextTick(function(){
                    console.log(document.getElementById("msgDiv"))
                })
            }
        }
    }
</script> 複製程式碼


點選前:

Vue.nextTick()理解


點選後:

Vue.nextTick()理解

注意:上面程式碼執行後第一次console.log(document.getElementById("msgDiv"))輸出的是null 這裡涉及一個重要的概念 非同步更新佇列。

Vue在觀察到資料變化時並不是直接更新DOM,而是開啟一個佇列,並緩衝在同一事件迴圈中發生的所有資料改變。在緩衝時會去除重複資料,從而避免不必要的計算和DOM操作。然後,在下一個事件迴圈tick中,Vue重新整理佇列並執行實際工作。 事實上,在執行this.showDiv = true;時,div仍然還是沒有被建立出來,直到下一個Vue事件迴圈時,才開始建立。$nextTick就是用來知道什麼時候DOM更新完成的,因此上述程式碼中第二個console.log(document.getElementById("msgDiv"))輸出的是<div id="msgDiv">你我貸</div>