watch和computed區別 及二者使用場景


1、區別

watch中的函數是不需要調用的
computed內部的 函數調用的時候不需要加()   ( 內部的不是函數,而是屬性對象只有get方法時的簡寫,其實它是屬性對象
 
watch  屬性監聽 監聽屬性的變化
computed:計算屬性通過屬性計算而得來的屬性
 
watch需要在數據變化時執行異步或開銷較大的操作時使用
對於任何復雜邏輯或一個數據屬性在它所依賴的屬性發生變化時,也要發生變化,這種情況下,我們最好使用計算屬性computed。 
 

computed 屬性的結果會被緩存,除非依賴的響應式屬性變化才會重新計算。主要當作屬性來使用;

computed中的函數必須用return返回最終的結果

當computed中的函數所依賴的屬性如果沒有發生改變的時候,那么調用當前函數的時候結果會從緩存中讀取

watch 一個對象,鍵是需要觀察的表達式,值是對應回調函數。主要用來監聽某些特定數據的變化,從而進行某些具體的業務邏輯操作;

 

 

2、使用場景
computed     
    當一個屬性受多個屬性影響的時候就需要用到computed
    最典型的例子: 購物車商品結算的時候
watch
    當一條數據影響多條數據的時候就需要用watch
    搜索數據
 
 
 
data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
  fullName:{
   get(){//回調函數 當需要讀取當前屬性值是執行,根據相關數據計算並返回當前屬性的值
      return this.firstName + ' ' + this.lastName
    },
   set(val){//監視當前屬性值的變化,當屬性值發生變化時執行,更新相關的屬性數據   (當fullName的值改變時就會執行set方法)
       //val就是fullName的最新屬性值
       console.log(val)
        const names = val.split(' ');
        console.log(names)
        this.firstName = names[0];
        this.lastName = names[1];
   }
   }
  }






handler方法和immediate屬性

 
                

這里 watch 的一個特點是,最初綁定的時候是不會執行的,要等到 firstName 改變時才執行監聽計算。那我們想要一開始就讓他最初綁定的時候就執行改怎么辦呢?我們需要修改一下我們的 watch 寫法,修改過后的 watch 代碼如下:

 
                
watch: {
  firstName: {
    handler(newName, oldName) {
      this.fullName = newName + ' ' + this.lastName;
    },
    // 代表在wacth里聲明了firstName這個方法之后立即先去執行handler方法
    immediate: true
  }
}
 
                

注意到handler了嗎,我們給 firstName 綁定了一個handler方法,之前我們寫的 watch 方法其實默認寫的就是這個handler,Vue.js會去處理這個邏輯,最終編譯出來其實就是這個handler

 
                

immediate:true代表如果在 wacth 里聲明了 firstName 之后,就會立即先去執行里面的handler方法,如果為 false就跟我們以前的效果一樣,不會在綁定的時候就執行。

 

 

當我們在在輸入框中輸入數據視圖改變obj.a的值時,我們發現是無效的。受現代 JavaScript 的限制 (以及廢棄 Object.observe),Vue 不能檢測到對象屬性的添加或刪除。由於 Vue 會在初始化實例時對屬性執行 getter/setter 轉化過程,所以屬性必須在 data 對象上存在才能讓 Vue 轉換它,這樣才能讓它是響應的。

默認情況下 handler 只監聽obj這個屬性它的引用的變化,我們只有給obj賦值的時候它才會監聽到,比如我們在 mounted事件鈎子函數中對obj進行重新賦值:

watch: {
  obj: {
    handler(newName, oldName) { //特別注意,不能用箭頭函數,箭頭函數,this指向全局
      console.log('obj.a changed');
    },
    immediate: true,  //刷新加載 立馬觸發一次handler
    deep: true  // 可以深度檢測到 obj 對象的屬性值的變化
  }
}

deep的意思就是深入觀察,監聽器會一層層的往下遍歷,給對象的所有屬性都加上這個監聽器,但是這樣性能開銷就會非常大了,任何修改obj里面任何一個屬性都會觸發這個監聽器里的 handler。

 深度監聽,為了發現對象內部值的變化,復雜類型的數據時使用,例如數組中的對象內容的改變,注意監聽數組的變動不需要這么做。

優化,我們可以是使用字符串形式監聽。

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

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

 

 

---------------------------------------------------------------------------------------------------------

2021-01-11

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

handler方法和immediate屬性

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

之前我們寫的 watch 方法其實默認寫的就是這個handler,Vue.js會去處理這個邏輯,最終編譯出來其實就是這個handler。

immediate:true代表如果在 wacth 里聲明了 viewDetials之后,就會立即先去執行里面的handler方法,如果為 false就跟我們以前的效果一樣,不會在綁定的時候就執行

deep屬性

watch 里面還有一個屬性 deep,默認值是 false,代表是否深度監聽當需要監聽一個對象的改變時,普通的watch方法無法監聽到對象內部屬性的改變,只有data中的數據才能夠監聽到變化,此時就需要deep屬性對對象進行深度監聽。

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

 

 

 

 

 

 


免責聲明!

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



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