vue數組中數據變化但是視圖沒有更新解決方案


場景

在我使用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;
    }
}

在改變其中是數據的時候,因為是數組。

參考這篇文章:

數組比較特殊需要使用與他匹配的變異方法變化數據才能被檢測到。

由於 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數據變化視圖沒更新去看響應式原理,和數組變異原理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM