はじめに
Vue.jsを使っていて、配列を変更しても画面に反映されないことがある。
たいていは配列を直接編集せずにpushメソッドやsliceメソッドを使うようにすることで解決するんだけど、
それでも解決できないケースがあり、結構ハマったのでメモしておく。
現象
ある配列をVue.jsで画面に表示していた。
WebSocketでサーバから新たなデータが送られてきたら、sliceやpushを使って配列を更新していたが、
配列を更新しても画面に反映されなかった。
原因
Vue.jsに備わっているレンダリングのキャッシュ機能と、私のv-forの誤った使い方が原因。
Vue.jsは、v-for使用時に指定するkeyに紐付ける形で、レンダリングする内容をキャッシュしている。
私はkeyにv-forのインデックスを指定してしまっていた。
こんな感じに↓
<!-- ダメな例 -->
<div v-for="(item, index) in items" :key="index">
(略)
</div>
これにより、配列更新後もVueはキャッシュを使ってレンダリングしていたため、画面が更新されなかったという訳だ。
対策
keyにv-forのインデックスを設定せず、それでいてキャッシュされないよう値が都度更新されるようにすればよい。
例えばこんな方法がある。
<!-- keyとしてitemに持たせた固有の値countを使う。 -->
<div v-for="item in items" :key="item.count">
(略)
</div>
// (略)
export default {
data() {
// 配列の各要素のcountの値を設定するときに使う。
itemCounter: 1,
// 配列
items: []
},
methods: {
AddItem(item) {
// items(配列)に新たに要素を追加するときに注意。
items.push({
// (略)
// Vue.jsがまだキャッシュしていない固有の値を設定する。
// itemCounterはインクリメントだけして、値を0に戻したり減らしたりしないようにする。
count: itemCounter++
});
}
}
};