1. 程式人生 > 實用技巧 >computed 和 watch

computed 和 watch

1. computed

computed 即計算的意思,是建立 vue例項 中的計算屬性,屬性值為一個物件,物件裡面是各種計算得來的資料變數,和 data 屬性裡面的變數一樣

也就是說該屬性用於存放計算得來的各種屬性,並且如果該計算屬性依賴的屬性沒有發生變化就不會重新觸發計算。

以下小例來自 vue 官網

var vm = new Vue({
  data: { a: 1 },
  computed: {
    // 僅讀取
    aDouble: function () {
      return this.a * 2
    },
    // 讀取和設定
    aPlus: {
      get: function () {
        return this.a + 1
      },
      set: function (v) {
        this.a = v - 1
      }
    }
  }
})
vm.aPlus   // => 2
vm.aPlus = 3
vm.a       // => 2
vm.aDouble // => 4 是屬性呼叫,不是函式呼叫

2. watch

watche 即監聽的意思,是對 data 屬性中的各種資料進行監聽的,會在監聽的資料發生變化時自動呼叫對應的監聽函式,因此監聽的屬性是 data 裡的資料,屬性值是相關的操作。如下所示:

new Vue({ 
    data: {
        n: 1,
        obj: {
          a: "a"
        },
        e: 2
    },
    watch:{
        n: function (newVal, oldVal) { 
            console.log(`a變化了,由${oldVal}變成了${newVal}`) 
        },
        obj() {
            console.log("obj 變了");
        },
        "obj.a": function() {
            console.log("obj.a 變了"); 
        },//屬性名有特殊符號 . 因此必須用引號括起來
        e: [
            'handle1',
            function  handle2 (val, oldVal){
                /do something
            }
        ] //陣列的放置依次執行多個函式操作
    }
})

immediate: true

watch 裡面的函式是隻有在資料變化時才會被自動呼叫,因此在資料初始化剛開始出現在頁面時是不會執行 watch 裡的監聽回撥的,因此若想在資料在初始化時就立即被呼叫,則要自行設定如下:

new Vue({
    data:{
        c: 4
    },
    watch:{
        handler: 'someMethod', //處理函式可以是 methods 裡的方法名
        immediate: true //將這一個屬性設定為 true,表示立即呼叫
    }
})

deep: true

當一個物件的內部屬性發生變化時,預設該屬性不會被認為發生變化,因為用到是 ===

操作符來判斷的是否改變,而物件內部資料改變但地址沒有改變,因此在比較僅改變物件內部資料時前後物件是比較的地址,結果是 obj 沒有改變,就只會呼叫內部屬性的監聽函式,而不會呼叫其所在物件的監聽函式,如下所示:

new Vue({ 
    data: {
        obj: {
          a: "a"
        }
    },
    watch:{
        obj() {
            console.log("obj 變了");
        },
        "obj.a": function() {
            console.log("obj.a 變了"); 
        },//屬性名有特殊符號 . 因此必須用引號括起來
    },
    template: `
        <div>
          //按鈕點選只會輸出 obj.a 變了,而不會輸出 obj 變了
          <button @click="obj.a += 'hi'">obj.a + 'hi'</button>
          //由於改變了整個物件,整個物件裡面的都會被改變,輸出 obj.a 變了,obj 變了
          <button @click="obj = {a:'a'}">obj = 新物件</button>
        </div>
    `
})

因此若想當物件內如資料改變時認為物件也改變了,觸發物件的監聽函式,則可在物件的監聽事件中加上一句 deep: true ,表示往深了看,用於複雜型別的深度監聽,用如下方法:

watch:{
    obj: {
      handler:function(){
        console.log("obj 變了");
      },
      deep: true //預設是 false
    }
}

3. 二者的區別

1. 分別是什麼

computed 是計算屬性,是 data 屬性的擴充套件,用於存放基於 data 資料經過各種計算得來的屬性,有依賴,有快取,當其所依賴的資料發生變化時 computed 會重新計算

watch 是監聽屬性,是對 data 中各種資料的監聽,在資料變化時做出相應處理。

2. 呼叫過程

computed 是會產生新的資料屬性,並對其進行監聽計算。

watch 只是單純地對當前資料進行監聽處理,不會產生新的資料屬性。