場景
在我使用vuex的過程中,使用computed獲取數據。獲取到的數據格式是這個樣子的
carts: [{}, {}, {}]
但是我在這個頁面中需要給這個數據額外添加一個數據字段
carts[index].editState = false;
遇到的問題
當我這樣開始做的時候,是直接在conputed計算屬性中獲取這個值,視圖沒有更新。
參考這篇文章:https://cn.vuejs.org/v2/guide/computed.html
計算屬性是依賴于data屬性中的數據存在的,只有data依賴中的數據變化,computed數據才會變化,視圖才會更新。
還是沒有更新
在上面把computed已經改為依賴data了,data進行變化,可是視圖還沒更新,于是我深入響應式原理。
參考這篇文章:https://cn.vuejs.org/v2/guide/reactivity.html
里面有一句話:
有時你想向已有對象上添加一些屬性,例如使用 Object.assign() 或 _.extend() 方法來添加屬性。但是,添加到對象上的新屬性不會觸發更新。在這種情況下可以創建一個新的對象,讓它包含原對象的屬性和新的屬性
// 代替 Object.assign(this.someObject, { a: 1, b: 2 })
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
使用這種給添加新屬性,我原來是直接通過點語法的,所以vue并沒有給我添加的新屬性增加get和set監聽。
解決辦法
使用Object.assign()創建新對象,并且computed的屬性依賴于data的屬性,類似下面這種:
data () {
return {
carts: this.$store.state.carts
}
},
computed: {
getCarts() {
for (let i = 0; i < this.carts.length; i++) {
this.carts[i] = Object.assign({}, this.carts[i], { editState: false });
}
this.carts = Object.assign({}, this.carts);
return this.carts;
}
}
在改變其中是數據的時候,因為是數組。
參考這篇文章:
https://cn.vuejs.org/v2/guide/list.html#數組更新檢測
https://cn.vuejs.org/v2/guide/list.html#注意事項
數組比較特殊需要使用與他匹配的變異方法變化數據才能被檢測到。
由于 JavaScript 的限制, Vue 不能檢測以下變動的數組:
當你利用索引直接設置一個項時,例如: vm.items[indexOfItem] = newValue
當你修改數組的長度時,例如: vm.items.length = newLength
為了解決第一類問題,以下兩種方式都可以實現和 vm.items[indexOfItem] = newValue 相同的效果, 同時也將觸發狀態更新:
// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice`
example1.items.splice(indexOfItem, 1, newValue)
example1.items.splice(newLength)
參考這兩篇文章,我是這樣寫的:
editNum(index) {
console.log(this.carts[index].editState);
let obj = this.carts[index];
obj.editState = !obj.editState;
this.$set(this.carts, index, obj);
console.log(this.carts[index].editState);
}
總結
遇到問題先谷歌和百度
猜測哪里出了問題,去看官方文檔原理
vue數據變化視圖沒更新去看響應式原理,和數組變異原理。