1. 程式人生 > 程式設計 >vue中watch和computed的區別與使用方法

vue中watch和computed的區別與使用方法

computed 計算屬性說明:

computed 是基於響應性依賴來進行快取的。只有依賴資料發生改變,才會重新進行計算(當觸發重新渲染,若依賴資料沒有改變,則 computed 不會重新計算)。若沒改變,計算屬性會立即返回之前快取的計算結果。

不支援非同步,當 computed 內有非同步操作時無效,無法監聽資料的變化的值。

computed 中的成員可以只定義一個函式作為只讀屬性,也可以定義成 get/set 變成可讀寫屬性

如果一個屬性是由其他屬性計算而來的,這個屬性依賴其他屬性,是一個多對一或者一對一,一般用 computed。

下面的計算屬性將不再更新,因為 Date.now() 不是響應式依賴:

computed: {
 now: function () {
 return Date.now()
 }
}

相比之下,每當觸發重新渲染時,呼叫方法將總會再次執行函式。

我們為什麼需要快取?假設我們有一個性能開銷比較大的計算屬性 A,它需要遍歷一個巨大的陣列並做大量的計算。然後我們可能有其他的計算屬性依賴於 A。如果沒有快取,我們將不可避免的多次執行 A 的 getter!如果你不希望有快取,請用方法來替代。

watch 監聽屬性說明:

不支援快取,資料變或者觸發重新渲染時,直接會觸發相應的操作。

watch 支援非同步

當一個屬性發生變化時,需要執行對應的操作;一對多時,一般用 watch。

監聽資料必須是 data 中宣告過或者父元件傳遞過來的 props 中的資料,當資料變化時,觸發其他操作,函式有兩個引數,immediate:元件載入立即觸發回撥函式執行,deep: 深度監聽,為了發現物件內部值的變化,複雜型別的資料時使用,例如陣列中的物件內容的改變,注意監聽陣列的變動不需要這麼做。注意:deep 無法監聽到陣列的變動和物件的新增,參考 vue 陣列變異,只有以響應式的方式觸發才會被監聽到。

watch 和 computed 的區別是:

相同點:

兩者都是觀察頁面資料變化的。

不同點:

  • computed 只有當依賴的資料變化時才會計算,會快取資料。
  • watch 每次都需要執行函式。watch 更適用於資料變化時的非同步操作。

使用 參考官方文件

computed 使用

型別:{ [key: string]: Function | { get: Function,set: Function } }

詳細:

計算屬性將被混入到 Vue 例項中。所有 getter 和 setter 的 this 上下文自動地繫結為 Vue 例項。

注意如果你為一個計算屬性使用了箭頭函式,則 this 不會指向這個元件的例項,不過你仍然可以將其例項作為函式的第一個引數來訪問。

computed: {
 aDouble: vm => vm.a * 2
}

計算屬性的結果會被快取,除非依賴的響應式 property 變化才會重新計算。注意,如果某個依賴 (比如非響應式 property) 在該例項範疇之外,則計算屬性是不會被更新的。

示例:

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

watch 使用 與 解釋

型別:{ [key: string]: string | Function | Object | Array }

詳細:

一個物件,鍵是需要觀察的表示式,值是對應回撥函式。值也可以是方法名,或者包含選項的物件。Vue 例項將會在例項化時呼叫 $watch(),遍歷 watch 物件的每一個 property。

示例:

var vm = new Vue({
 data: {
  a: 1,b: 2,c: 3,d: 4,e: {
   f: {
    g: 5,watch: {
  a: function (val,oldVal) {
   console.log('new: %s,old: %s',val,oldVal)
  },// 方法名
  b: 'someMethod',// 該回調會在任何被偵聽的物件的 property 改變時被呼叫,不論其被巢狀多深
  c: {
   handler: function (val,oldVal) {
    ;/_ ... _/
   },// or handler:'方法名'
   deep: true,// 該回調將會在偵聽開始之後被立即呼叫
  d: {
   handler: 'someMethod',// or handler: function(val,oldVal){}
   immediate: true,// 你可以傳入回撥陣列,它們會被逐一呼叫
  e: [
   'handle1',function handle2(val,oldVal) {
    /* ... */
   },{
    handler: function handle3(val,oldVal) {
     /* ... */
    },/* ... */
   },],// watch vm.e.f's value: {g: 5}
  'e.f': function (val,oldVal) {
   ;/_ ... _/
  },})
vm.a = 2 // => new: 2,old: 1

說明: 對應上方的 a~e

a: 監聽一個屬性,需要使用前後變化值時使用

b: 監聽一個屬性,不會使用到改變前後的值,只為了執行一些方法,可以使用字串代替 字串代表方法名

c: 在監聽一個物件時,當物件內部的屬性被改變時,無法觸發 watch,設定 deep 為 true 後,無論巢狀多深,只要屬性值被改變都會觸發監聽。但這種方式開銷會較大,監聽器會一層一層往下找,為每個屬性新增監聽器。

如果我們只是監聽物件的某個屬性改變時,可以這樣做:

  watch:{
  'user.name':{
   handler: 'method'
  }

 }

d: watch 是在監聽屬性改變時才會觸發,元件建立時可能不會執行,因此我們可以設定 immediate: true,就會讓在元件建立後 watch 能夠立即執行一次。就不用在 create 的時候去修改屬性啦。

handelr: 觸發監聽執行的方法(需要用到改變前後的值時,可換成函式)

immediate: 監聽開始之後被立即呼叫

e: 監聽一個屬性,執行多個函式包括回撥等

注意,不應該使用箭頭函式來定義 watcher 函式 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭頭函式綁定了父級作用域的上下文,所以 this 將不會按照期望指向 Vue 例項,this.updateAutocomplete 將是 undefined。

總結

到此這篇關於vue中watch和computed的區別與使用方法的文章就介紹到這了,更多相關vue watch和computed的區別內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!