在Vue的組件中,computed計算屬性經常被用來表示需要根據其他變量計算而來的屬性值,通常我們會期望computed可以隨著依賴數據的變化而動態更新。但是有時候,我們會遇到computed不更新的問題,這可能是因為以下原因:
computed: { result() { return this.items.reduce((total, item) =>total + item.count, 0) } }
1.依賴數據沒有變化
這是最常見的computed不更新問題,如果依賴數據沒有發生變化,那么computed也不會更新。比如下面的例子,雖然items數組中的對象數量發生了變化,但是對象內部的count屬性沒有變化,導致computed不會更新:
this.items.push({ count: 0 })
正確的做法是,直接修改對象內部的count屬性,或者使用Vue.set方法強制更新對象:
// 修改內部屬性 this.items[this.items.length - 1].count++ // 強制更新對象 Vue.set(this.items, this.items.length, { count: 0 })
2.依賴數據為非響應式對象
如果computed的依賴數據是一個普通的javascript對象,而不是Vue實例中的響應式數據,那么computed也不會更新。因為Vue只會追蹤響應式數據的變化,如果數據本身不是響應式的,那么computed就無法感知其變化。比如下面的例子中,items是一個普通的javascript數組,computed不會感知其變化:
data() { return { items: [] } }, computed: { result() { return this.items.length } }
正確的做法是,將items數組改為響應式的:
data() { return { items: [] } }, computed: { result() { return this.items.length } }, created() { this.$set(this, 'items', []) // 或者 this.items = this.$set(this, 'items', []) }
3.computed方法名和依賴數據屬性名沖突
如果computed方法名和某個依賴數據屬性名沖突,那么computed就不會更新。比如下面的例子中,items和result方法同名,computed不會更新:
data() { return { items: [], result: '' } }, computed: { result() { return this.items.join(',') } }
正確的做法是,換一個方法名:
data() { return { items: [], result: '' } }, computed: { listResult() { return this.items.join(',') } }
總之,如果你遇到computed無效的問題,可以檢查一下上述幾個方面,看看是不是哪里做得不夠好。