Vue 偵聽器 watch 擴展之立即觸發回調、深度監聽和注銷


一、立即觸發回調

watch 最初綁定時是不會執行的,需要等監聽的內容改變時才執行監聽計算

那我們想要一開始綁定的時候就執行該怎么辦呢?

可以修改一下 watch 寫法,如下:

watch: {
  firstName: {
    handler(newName, oldName) {
      this.fullName = newName + ' ' + this.lastName;
    },
    { immediate: true }
  }
}

上述寫法用到了 handler 方法和 immediate 屬性

 

1、handler 方法

原來我們 watch 中默認寫的就是這個 handler,Vue 會去處理這個邏輯,最終編譯出來其實就是這個 handler

 

2、immediate 屬性

指定 immediate: true 將立即以表達式的當前值觸發回調,即在 wacth 中聲明了 firstName 之后就會立即執行里面的 handler 方法,如果為 false 就跟原來的效果一樣,不會在綁定的時候就執行

 

二、深度監聽

受 JavaScript 的限制,Vue 無法檢測到對象屬性的變化

例如,在下面的輸入框中輸入數據改變 obj.a 的值是無效的

<div>
      <input type="text" v-model="obj.a">
</div>
 
new Vue({
  el: '#root',
  data: {
    obj: {
      a: 123
    }
  },
  watch: {
    obj: {
      handler(newVal, oldVal) {
         console.log('obj.a changed');
      },
      { immediate: true }
    }
  } 
})

默認情況下 handler 只監聽 obj 這個屬性的引用的變化,只有給 obj 賦值時它才會被監聽到

如果我們需要監聽 obj 的屬性 a 該怎么做呢?這時候就需要用到 deep 屬性了

 

1、deep 屬性

watch 中有一個屬性 deep,默認值為 false,表示是否進行深度監聽

watch: {
  obj: {
    handler(newVal, oldVal) {
      console.log('obj.a changed');
    },
    {
      immediate: true,
      deep: true
    }
  }
} 

設置 deep 為 true 后,監聽器會一層層的往下遍歷,給對象的所有屬性都加上這個監聽器,這樣就可以監聽到屬性 a 了

但這樣性能消耗會非常大,只要修改 obj 中任一屬性都會觸發這個監聽器里的 handler,因此我們可以使用字符串形式監聽來進行優化:

watch: {
  'obj.a': {
    handler(newVal, oldVal) {
      console.log('obj.a changed');
    },
    {
      immediate: true
      // deep: true
    }
  }
} 

這樣 Vue 會一層層解析下去,直到遇到屬性 a,然后才給 a 設置監聽函數

 

三、注銷

1、unwatch 方法

const unwatch = app.$watch('text', (newVal, oldVal) => {
  console.log('text changed');
})
 
unwatch();  // 手動注銷 watch

注意在帶有 immediate 選項時,不能在第一次回調時取消偵聽給定的 property

// 這會導致報錯
var unwatch = vm.$watch(
  'value',
  function () {
    doSomething()
    unwatch()
  },
  { immediate: true }
)

如果仍想在回調內部調用一個取消偵聽的函數,應該先檢查其函數的可用性:

var unwatch = vm.$watch(
  'value',
  function () {
    doSomething()
    if (unwatch) {
      unwatch()
    }
  },
  { immediate: true }
)

 


免責聲明!

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



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