vue的watch,computed和methods里面的方法

vue的watch和computed到底哪里不同?這個問題在我看文檔的時候沒有很懂,以至于我就忘記了computed也會觸發(fā)更新,結(jié)果悲劇了。。。吃一塹長一智,補課走起。

第一步必須是查看文檔https://cn.vuejs.org/v2/guide/computed.html

com1.png

明顯上面這句話的含義是模版里面展示的數(shù)據(jù)如果需要復(fù)雜的處理后展示我們應(yīng)該用計算屬性(這個和監(jiān)聽更新并無關(guān)系),繼續(xù)往下看,它給出了一個例子

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 計算屬性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 實例
      return this.message.split('').reverse().join('')
    }
  }
})

結(jié)果:
Original message: "Hello"
Computed reversed message: "olleH"
然后我們主動修改它的依賴數(shù)據(jù)message

vm.message = 'Goodbye'
console.log(vm.reversedMessage)

此時的結(jié)果是'eybdooG'。也就是說你可以像綁定普通屬性一樣在模板中綁定計算屬性。Vue 知道 vm.reversedMessage 依賴于 vm.message,因此當(dāng) vm.message 發(fā)生改變時,所有依賴 vm.reversedMessage 的綁定也會更新。

然后我們把上面的效果用methods里面的方法去實現(xiàn)一下

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage() }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  methods: {
    reversedMessage () {
      return this.message.split('').reverse().join('')
    }
  }
})

結(jié)果依然是:
Original message: "Hello"
Computed reversed message: "olleH"

也就是說我們兩種方式結(jié)果是一樣的(請相信每一個實現(xiàn)都會有差異,作者不會無緣無故實現(xiàn)幾個沒有差異的東西給你),這個時候去看文檔吧~

com3.png

上面清楚的說明了一個問題,computed是緩存的只要依賴的數(shù)據(jù)不更改他就不會重新計算更新,而methods里面的方法是每次刷新都會去執(zhí)行的

最后來看看watch。官方給出了一句解釋叫做當(dāng)需要在數(shù)據(jù)變化時執(zhí)行異步或開銷較大的操作時,這個方式是最有用的。這句話怎么理解?看看它的例子就明白了,watch 選項允許我們執(zhí)行異步操作 (訪問一個 API),限制我們執(zhí)行該操作的頻率,并在我們得到最終結(jié)果前,設(shè)置中間狀態(tài)

好了文檔上就這么多,我們運用到實踐中會是怎么樣的呢

示例一:
根據(jù)路由的變化獲取id去重新請求接口并展示數(shù)據(jù)(本質(zhì)上就是watch路由的變化)

watch: {
  $route () {
    this.getList() // 這里為觸發(fā)請求新列表的函數(shù)
  }
}

分析:只監(jiān)聽一個值的變化,然后重新去計算

示例二:
進入頁面之后要從store(vuex)里面去獲取一個異步請求回來的數(shù)據(jù)(你不能確認(rèn)開始獲取是存在的)

computed: {
  menu () {
    return this.$store.state.storeMenu
  }
}

分析:this.$store.state.storeMenu這個在進入頁面的時候因為需要dispatch去觸發(fā)一個異步的請求所以當(dāng)你獲取的時候不一定存在,而當(dāng)store里面存在了因為menu計算依賴的數(shù)據(jù)變化它會重新計算填充。當(dāng)然你可能會說如果我直接dispatch那個函數(shù)里加一個promise然后就可以保證拿到數(shù)據(jù)了,這個當(dāng)然是,例如我在action里面寫成下面的方式:

export const getMenuList = ({ commit }) => {
  return new Promise((resolve, reject) => {
    fetch('xxxxxx').then(res => {
      commit(types.GET_MENU_LIST, {
        menuList: res
      })
      resolve()
    })
  })
}

上面的方式確實可以保證你有數(shù)據(jù),但是你如果有N處要進入頁面就需要展示這個數(shù)據(jù)呢?不能多次dispatch吧

methods里面的方法就不再舉例子了,它的好處絕對是可掌控,你可以主動的調(diào)用,而不是主動的去監(jiān)聽某個數(shù)據(jù)。

根據(jù)上面的學(xué)習(xí)和自己使用的經(jīng)驗做一個總結(jié):

  1. computed是計算屬性,是依賴其他屬性計算得出的結(jié)果;watch是監(jiān)聽某一個值的變化執(zhí)行對應(yīng)的方法
  2. computed的值在getter執(zhí)行后是會緩存的,只有在它依賴的屬性值改變之后,下一次獲取computed的值時才會重新調(diào)用對應(yīng)的getter來計算;watch在每次監(jiān)聽的值變化時,都會執(zhí)行回調(diào)。如果一個值依賴多個屬性(多對一),用computed肯定是更加方便的。如果一個值變化后會引起一系列操作,或者一個值變化會引起一系列值的變化(一對多),用watch更加方便一些
  3. watch的回調(diào)里面會傳入監(jiān)聽屬性的新舊值,通過這兩個值可以做一些特定的操作;computed通常就是簡單的計算
  4. methods里面的方法不包含主動監(jiān)聽的能力,且相對于computed來講沒有緩存能力,每次會重新執(zhí)行(在SPA切換的時候比較明顯);但比較靈活,可以手動去調(diào)取
  5. 它們并沒有哪個更底層。watch和computed的共同之處就是每個定義的屬性都單獨建立了一個Watcher對象,當(dāng)然這個能力是方法所不具有的
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容