vue computed使用_vue computed正确使用方式
模板內的表達式非常便利,但是設計它們的初衷是用于簡單運算的。在模板中放入太多的邏輯會讓模板過重且難以維護,所以,對于復雜邏輯,vue 提倡使用計算屬性。需要特別說明:計算屬性的 getter 函數(shù)是沒有副作用 (side effect) 的,這使它更易于測試和理解 — from Vue計算屬性
討論 computed 和 watch 之間的區(qū)別前,我們先看下 computed 和 methods 有何區(qū)別?computed or methods
理論上,computed 所有實現(xiàn)可以使用 methods 完全替換。
<p>Reversed message: "{{ reversedMessage() }}"</p> <p>Reversed message: "{{ reversedMessage }}"</p> // 計算屬性 computed: {reversedMessage () {return this.message.split('').reverse().join('')} } // 方法 methods: {reversedMessage: function () {return this.message.split('').reverse().join('')} }計算屬性是基于它們的響應式依賴進行緩存的。只在相關響應式依賴發(fā)生改變時它們才會重新求值。這就意味著只要 message 還沒有發(fā)生改變,多次訪問 reversedMessage計算屬性會立即返回之前的計算結果,而不必再次執(zhí)行函數(shù)。而方法卻會執(zhí)行。
這也同樣意味著下面的計算屬性將不再更新,因為 Date.now() 不是響應式依賴:
computed: {now: function () {return Date.now()} }我們?yōu)槭裁葱枰彺?#xff1f;假設我們有一個性能開銷比較大的計算屬性 A,它需要遍歷一個巨大的數(shù)組并做大量的計算。然后我們可能有其他的計算屬性依賴于 A 。如果沒有緩存,我們將不可避免的多次執(zhí)行 A 的 getter!如果你不希望有緩存,請用方法來替代。
相同之處: computed 和 methods 將被混入到 Vue 實例中。vm.reversedMessage/vm.reversedMessage() 即可獲取相關計算屬性/方法。
接下來,看下 computed 和 watch 有何區(qū)別?computed or watch
Vue 提供了一種更通用的方式來觀察和響應 Vue 實例上的數(shù)據(jù)變動:偵聽屬性。當你有一些數(shù)據(jù)需要隨著其它數(shù)據(jù)變動而變動時,你很容易濫用 watch,然而,通常更好的做法是使用計算屬性而不是命令式的 watch 回調。
當需要在數(shù)據(jù)變化時執(zhí)行異步或開銷較大的操作時, watch 方式是最有用的。其允許我們執(zhí)行異步操作 (訪問一個 API),限制我們執(zhí)行該操作的頻率,并在我們得到最終結果前,設置中間狀態(tài)。這些都是計算屬性無法做到的。
methods: {getAnswer: function () {this.answer = 'Thinking...'var vm = thisaxios.get('https://yesno.wtf/api').then(function (response) {vm.answer = _.capitalize(response.data.answer)}).catch(function (error) {vm.answer = 'Error! Could not reach the API. ' + error})} }, created: function () {// debounce 反彈函數(shù)this.debouncedGetAnswer = _.debounce(this.getAnswer, 500) } 這樣來看,watch 完全可以替代 computed ?什么情況下,只能使用computed呢?回顧 computed 最大特點就是緩存,所以上述問題可以轉換為:哪些情況下,我們需要依賴緩存?
示例:父組件給子組件傳值,值的類型為引用類型
父組件
<template><div><child :user="user"></child><label for="user">parent:</label><input id="user" type="text" v-model="user.name"></div> </template> <script> import Child from './child.vue' export default {data () {return {user: { name: 'ligang' }}},components: { Child } } </script>子組件
<template><div>child: {{user}}</div> </template> <script> export default {name: 'child',props: ['user'] } </script>現(xiàn)在有這樣一個需求,子組件中需要同時顯示改變前和改變后的值。
So Easy,只需要在 watch 中保存 oldVal 即可。
<template><div><div>child:</div><div>修改前:{{oldUser}} 修改后:{{user}}</div></div> </template> <script> export default {name: 'child',props: ['user'],data () {return {oldUser: {}}},watch: {user: {handler (val, oldVal) {this.oldUser = oldVal || val},deep: true,immediate: true}} } </script>查看結果,WTF,啥情況~~
示例問題在于,user為引用類型,且 watch 沒有做緩存,導致了修改的是同一個對象,所以,watch 方法中val === olVal is true!!
如何達到要求呢,這里我們就可以借用 computed 緩存的特性,來完成上述情況。
計算屬性的結果會被緩存,除非依賴的響應式屬性變化才會重新計算。注意,如果某個依賴 (比如非響應式屬性) 在該實例范疇之外,則計算屬性是不會被更新的。 — vue-computed-api
<template><div><div>child:</div><div>修改前:{{oldUser}} 修改后:{{user}}</div></div> </template> <script> export default {name: 'child',props: ['user'],data () {return {oldUser: {}}},// 緩存 userInfo computed: {userInfo () {return { ...this.user }}},watch: {userInfo: {handler (val, oldVal) {this.oldUser = oldVal || val},deep: true,immediate: true}} } </script>需要注意:{ ...this.user } 或者使用 Object.assign({}, this.user) 來創(chuàng)建新的引用!
歡迎關注 「 Super 前端 」微信公眾號版權聲明:本文原創(chuàng)自我的博客李剛的學習專欄
總結
以上是生活随笔為你收集整理的vue computed使用_vue computed正确使用方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统:再见CentOS,将于本月底终
- 下一篇: html5倒计时秒杀怎么做,vue 设