在Vue中,你可能經常遇到這個問題,數據明明已經變化,但是相應的視圖卻沒有更新。
舉個例子:
一個10行的列表,選中一行,該行的背景色變化。
上代碼:
CSS: .itemIsSelected{ background:red; } HTML: <tr v-for="(item,index) in listData" @click="lineClick(item)" :class='{itemIsSelected:item.isSelected}'> <td>{{item.a}}</td> <td>{{item.a}}</td> <td>{{item.a}}</td> <td>{{item.a}}</td> </tr> JavaScript: new Vue({ el:"#app", data:{ listData:[] }, mounted:function(){ this.getList() }, methods:{ lineClick(item){ console.log(item) item.isSelected = item.isSelected; console.log(item) }, getList(){ axios().then(res => { this.listData = res.list; }) } } })
欣喜一回,終於寫完了,嘗試一波,點擊一行,控制台輸出對應的 item 的對象
這個時候你卻發現,該行的背景色並沒有隨之改變。
再次點擊當前行,控制台又輸出對應 item的對象
檢查數據,第一次輸出的 item 的 isSelected 確實是 true ,第二次輸出的 item 的 isSelected 確實是 false,
但是,視圖就是沒有更新
這時候,不難發現一個問題,兩次輸出的 item 對象,有一個共同點
item 的 isSelected 屬性在控制台直接是可見的,而其他對象需要手動點擊一次,才可以看到
並且,item 的其他屬性,有對應的 getter 和 setter 方法, 而 isSelected 屬性沒有
問題定位到了,如何解決。
問題是:vue 中,是通過數據的 getter 和setter 來做相應的視圖更新,該例子中 isSelected 沒有對應的 getter 和setter
通常我的做法是,在數據請求回來的時候,在數據給到 vue 的data 之前,給數據手動增加 isSelected 為false。
即 在 this.listData = res.list 之前 (一定要在數據給到 vue 實例 之前 之前 之前)
做如下操作:
res.list.forEach((item) => { item.isSelected = false; })
再次嘗試 ok !!!