VUE中數組更新後,頁面沒有動態刷新問題

數組變更檢測注意事項:

由於 JavaScript 的限制,Vue 不能檢測以下數組的變動:

  1. 當你利用索引直接設置一個數組項時,例如:vm.items[indexOfItem] = newValue
  2. 當你修改數組的長度時,例如:vm.items.length = newLength

舉個例子:

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是響應性的
vm.items.length = 2 // 不是響應性的

也就是說,直接設置數組的某一項的值,雖然改變了數組的值,但視圖上顯示的仍爲數組之前的值,數據的響應失效了。出現這種現象的根本原因是什麼呢?

首先我們先來了解vue數據響應的原理。官方文檔的解釋:

當你把一個普通的 JavaScript 對象傳給 Vue 實例的 data 選項,Vue 將遍歷此對象所有的屬性,並使用 Object.defineProperty 把這些屬性全部轉爲 getter/setter。

也就是說當改變data中屬性的值時會觸發其相應setter的調用,從而實現響應的操作。但getter和setter是有侷限性的。我們先來看下面的這個例子:

當該屬性的值爲一個數組時,通過索引修改數組某一項的值或使用數組的某些方法修改數組並不能觸發set;當屬性的值爲一對象時,直接修改對象中屬性的值時也無法觸發set。

爲了解決當你利用索引直接設置一個數組項問題,以下兩種方式都可以實現和 vm.items[indexOfItem] = newValue 相同的效果,同時也將在響應式系統內觸發狀態更新:

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

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

你也可以使用 vm.$set 實例方法,該方法是全局方法 Vue.set 的一個別名:

vm.$set(vm.items, indexOfItem, newValue)

爲了解決當你修改數組的長度問題,你可以使用 splice

vm.items.splice(newLength)

對象變更檢測注意事項:

還是由於 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:

var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` 現在是響應式的

vm.b = 2
// `vm.b` 不是響應式的

 

對於已經創建的實例,Vue 不允許動態添加根級別的響應式屬性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套對象添加響應式屬性。例如,對於:

var vm = new Vue({
  data: {
    userProfile: {
      name: 'Anika'
    }
  }
})

當修改對象的屬性或爲對象添加屬性時,應該使用以下方法:

Vue.set(vm.userProfile, 'age', 27)

或者

vm.$set(vm.userProfile, 'age', 27)

有時你可能需要爲已有對象賦值多個新屬性,比如使用 Object.assign() 或 _.extend()。在這種情況下,你應該用兩個對象的屬性創建一個新的對象。所以,如果你想添加新的響應式屬性,不要像這樣:

Object.assign(vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

你應該這樣做:

vm.userProfile = Object.assign({}, vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

由於數據響應原理機制, Vue 不允許動態添加根級響應式屬性,所以你必須在初始化實例前聲明所有可能用到的根級響應式屬性,且爲這些屬性都設一個初值,哪怕只是一個空值。

迴歸正題,我項目中遇到的這個問題,解決方法:

1. 運用this.$forceUpdate()強制刷新。

2. 使用vm.$set(vm.items, indexOfItem, newValue)

eg.  vm.$set(vm.dataList[i],  picUrl, 'data:image/jpg;base64,' + response.data)    }, created() { }, mounted() { } };

複製代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章