在vue中 列表渲染算是最常用的功能之一,但是在列表渲染中有個一比較明顯的問題:
在列表渲染中,經常發生數據變化,但是視圖層並未改變的狀況,根據官方:
由於 JavaScript 的限制,Vue 不能檢測以下變動的數組:
- 當你利用索引直接設置一個項時,例如:
vm.items[indexOfItem] = newValue - 當你修改數組的長度時,例如:
vm.items.length = newLength
還有一個注意點是 :不論是當前循環的數組數據,還是在循環列表中用到的數組數據,都不能在視圖同步響應這兩種數據改變。
例如:
<template v-for="(item, index) in receiveData"> <a :class="list[index]?'visiteColor':''" :key="item.id" @click="linkColor(index)"> <p class="dateFont">{{item.date}}</p> <p>{{list}}</p> </a> </template>
這時候,數組receiveData 和數據 list 是都不能通過 索引改變視圖層的,所以就會出現 數據改變,但是視圖不變的情況
解決方法官方也給了:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set 實例方法,該方法是全局方法 Vue.set 的一個別名:
vm.$set(vm.items, indexOfItem, newValue)
為了解決第二類問題,你可以使用 splice:改變數組的長度
vm.items.splice(newLength)
我在組件中寫的例子:
export default { data () { return { list: [true], receiveData: [ { date: '2018-06-10' }, { date: '2018-06-10' } ] }; }, methods: { linkColor (index) { for (let i = 0; i < this.list.length; i++) { if (i !== index) { // 循環中的數組賦值 this.$set(this.list, i, false); this.$set(this.list, index, true); } } console.log(this.list); } } };
