1. 程式人生 > >理解 $nextTick 的作用

理解 $nextTick 的作用

有同學在看 Vue 官方文件時,對 API 文件中的 Vue.nextTick 和 vm.$nextTick 的作用不太理解。

其實如果看一下深入響應式原理 - vue.js中的有關內容,可能會有所理解,不過有些同學可能看到這個標題之後就選擇跳過了,因此這裡簡述如下:

Vue 實現響應式並不是資料發生變化之後 DOM 立即變化,而是按一定的策略進行 DOM 的更新。

$nextTick 是在下次 DOM 更新迴圈結束之後執行延遲迴調,在修改資料之後使用 $nextTick,則可以在回撥中獲取更新後的 DOM,API 文件中官方示例如下:

new Vue({
  // ...
  methods: {
    // ...
    example: function () {
      // modify data
      this.message = 'changed'
      // DOM is not updated yet
      this.$nextTick(function () {
        // DOM is now updated
        // `this` is bound to the current instance
        this.doSomethingElse()
      })
    }
  }
})
有些同學可能不大理解什麼叫 DOM is now updated,在深入響應式原理 - vue.js中的示例情況也比較罕見,Vue 模板中直接在根無素中進行插值,然後在例項方法中使用了 this.$el.textContent 來獲得更新之後的 DOM。

為了更好地理解這一點,修改示例如下:

模板——

<div class="app">
  <div ref="msgDiv">{{msg}}</div>
  <div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
<div v-if="msg2">Message got inside $nextTick: {{msg2}}</div> <div v-if="msg3">Message got outside $nextTick: {{msg3}}</div> <button @click="changeMsg"> Change the Message </button> </div>

Vue 例項化——

new Vue({
  el: '.app',
  data: {
    msg: 'Hello Vue.'
, msg1: '', msg2: '', msg3: '' }, methods: { changeMsg() { this.msg = "Hello world." this.msg1 = this.$refs.msgDiv.innerHTML this.$nextTick(() => { this.msg2 = this.$refs.msgDiv.innerHTML }) this.msg3 = this.$refs.msgDiv.innerHTML } } })

點選按鈕前的介面:

點選按鈕之後,介面如下,注意觀察三個條件渲染的結果之間的差異。

看完這個示例,也許有人會問,我在 Vue 例項方法中修改了資料,然後再在 $nextTick 回撥中獲取該資料在相應 DOM 元素所繫結的內容(或屬性)殊無必要,我為什麼需要這樣的 API 呢?

考慮這樣一種場景,你有一個 jQuery 外掛,希望在 DOM 元素中某些屬性發生變化之後重新應用該外掛,這時候就需要在 $nextTick 的回撥函式中執行重新應用外掛的方法。