Vue陣列更新檢測無效

血手人屠_發表於2018-07-30

        Object.observe(),它可以非同步觀察Javascript中物件變化的方法,而無需你去使用一個其他的JS庫。它允許一個觀察者接收一個按照時間排序的變化記錄序列,這個序列描述的是一列被觀察的物件所發生的變化。

     vue中Observer的建構函式

constructor (value: any) {
    this.value = value
    this.dep = new Dep()
    this.vmCount = 0
    def(value, '__ob__', this)
    if (Array.isArray(value)) {
        const augment = hasProto
        ? protoAugment
        : copyAugment
        augment(value, arrayMethods, arrayKeys)
        this.observeArray(value)
    } else {
        this.walk(value)
    }
}

value是需要被觀察的資料物件,在建構函式中,會給value增加__ob__屬性,作為資料已經被Observer觀察的標誌。

Vue框架對陣列的push、pop、shift、unshift、sort、splice、reverse方法進行了改造(變異方法),解決了呼叫這些函式改變陣列後無法觸發更新的問題。

由於 JavaScript 的限制(Observer),Vue 不能檢測以下變動的陣列:

1、當你利用索引直接設定一個項時,例如:vm.items[indexOfItem] = newValue

2、當你修改陣列的長度時,例如:vm.items.length = newLength

為了解決第一類問題,以下兩種方式都可以實現和 vm.items[indexOfItem] = newValue 相同的效果,同時也將觸發狀態更新:

Vue.set(vm.items, indexOfItem, newValue)
vm.items.splice(indexOfItem, 1, newValue)

為了解決第二類問題,你可以使用 splice

相關文章