vue中watch, computed 的詳細用法及對比

1.computed

1.1 get用法

  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }

注意 fullName不可在data裏面定義,因爲對應的computed作爲計算屬性定義fullName並返回對應的結果給這個變量,變量不可被重複定義和賦值

1.2 get和set用法

data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
  fullName:{
   get(){//回調函數 當需要讀取當前屬性值是執行,根據相關數據計算並返回當前屬性的值
      return this.firstName + ' ' + this.lastName
    },
   set(val){//監視當前屬性值的變化,當屬性值發生變化時執行,更新相關的屬性數據
       //val就是fullName的最新屬性值
       console.log(val)
        const names = val.split(' ');
        console.log(names)
        this.firstName = names[0];
        this.lastName = names[1];
   }
   }
  }

2. watch

2.1用法

  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
     firstName: function (val) {
     this.fullName = val + ' ' + this.lastName
  },
  lastName: function (val) {
     this.fullName = this.firstName + ' ' + val
   }
   }

注意上面是監聽firstName和lastName的變化,但是僅限簡單數據類型

2.2 監聽複雜數據類型
當需要監聽一個對象的改變時,普通的watch方法無法監聽到對象內部屬性的改變,只有data中的數據才能夠監聽到變化,此時就需要deep屬性對對象進行深度監聽。

data(){
      return{
        first:{
          second:0
        }
      }
    },
    watch:{
      secondChange:{
        handler(oldVal,newVal){
          console.log(oldVal)
          console.log(newVal)
        },
        deep:true
      }
    },

console.log打印的結果,發現oldVal和newVal值是一樣的,所以深度監聽雖然可以監聽到對象的變化,但是無法監聽到具體對象裏面那個屬性的變化
原因:oldVal和newVal值一樣的原因是它們索引同一個對象/數組。Vue 不會保留修改之前值的副本

設置deep: true 則可以監聽到first.second的變化,此時會給first的所有屬性都加上這個監聽器,當對象屬性較多時,每個屬性值的變化都會執行handler。如果只需要監聽對象中的一個屬性值,則可以做以下優化:使用字符串的形式監聽對象屬性


watch: {
 first.second: {
      handler(newName, oldName) { 
     // ...    
  },
      deep: true,
      immediate: true
    }

這樣就只會給對象的某個特定的屬性加監聽器。

數組(一維、多維)的變化不需要通過深度監聽,對象數組中對象的屬性變化則需要deep深度監聽。

3.3使用 immediate和handler

這樣使用watch時有一個特點,就是當值第一次綁定的時候,不會執行監聽函數,只有值發生改變纔會執行。如果我們需要在最初綁定值的時候也執行函數,則就需要用到immediate屬性。

比如當父組件向子組件動態傳值時,子組件props首次獲取到父組件傳來的默認值時,也需要執行函數,此時就需要將immediate設爲true


new Vue({
  el: '#root',
  data: {
    cityName: ''
  },
  watch: {
    cityName: {
      handler(newName, oldName) {
        // ...      },
      immediate: true
    }
  } 
})

監聽的數據後面寫成對象形式,包含handler方法和immediate,之前我們寫的函數其實就是在寫這個handler方法;

immediate表示在watch中首次綁定的時候,是否執行handler,值爲true則表示在watch中聲明的時候,就立即執行handler方法,值爲false,則和一般使用watch一樣,在數據發生變化的時候才執行handler。

3 . 監聽對象單個屬性方法二
watch如果想要監聽對象的單個屬性的變化,必須用computed作爲中間件轉化,因爲computed可以取到對應的屬性值

data(){
      return{
        'first':{
          second:0
        }
      }
    },
    computed:{
      secondChange(){
        return this.first.second
      }
    },
    watch:{
      secondChange(){
        console.log('second屬性值變化了')
      }
    },

4 . computed和watch的區別
4.1 computed特性
1.是計算值,
2.應用:就是簡化tempalte裏面{{}}計算和處理props或$emit的傳值
3.具有緩存性,頁面重新渲染值不變化,計算屬性會立即返回之前的計算結果,而不必再次執行函數

4.2 watch特性
1.是觀察的動作,
2.應用:監聽props,$emit或本組件的值執行異步操作
3.無緩存性,頁面重新渲染時值不變化也會執行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章