- 開発技術
Vue.jsのv-forでkeyが必要な理由
- #VueJS
はじめに
【エンジニア募集中】フルリモート可◎、売上/従業員数9年連続UP、平均残業8時間、有給取得率90%、年休124日以上 etc. 詳細はこちらから>
Vue.jsのv-forディレクティブでは、要素を配列にバインドしてレンダリングをすることができます。そしてバインドを行う際、各要素に一意のkey属性を指定することが推奨されています。本記事では、なぜ推奨されているのかについて述べます。
仮想DOMとは
メモリ上に保持された(実際のDOMとは異なる)仮想的なDOMで、パフォーマンスの向上や効率的なDOM更新のため、Vue.jsやReactなどで使用されています。リアクティブなデータが変更されたとき、まず仮想DOMが変更され、変更内容の抽出(差分計算)が行われ、実際のDOMに変更部分が反映されるという処理が行われます。差分計算では、仮想DOMで「更新しなければならない部分」のみを抽出して処理を行います。
DOMノードと要素番号のずれ
例えば、次のようにデータを変更すると考えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<html> <head> <meta charset="UTF-8"> <title>flowers</title> </head> <body> <div id="app"> <ul> <li v-for="item in items" :key="index"> {{ item.text }} <button @click="removeItem(index)">X</button> </li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> <script> new Vue({ el: '#app', data: { items: [ { id: 1, text: 'Dalia' }, { id: 2, text: 'Tulip' }, { id: 3, text: 'Rose' }, ] }, methods: { removeItem(index){ this.items.splice(index, 1); } } }); </script> </body> </html> |
Tulipは削除されず、先頭のDaliaが削除されてしまいます。この問題は、Vue.jsが変更内容の抽出を行う過程で、配列のどの要素が変更されたのか正確に把握できず、DOMノードが再利用されてしまうことに起因します。
先ほどの例では、Tulipの削除を行う際にindexを基に再レンダリングを行うため、先頭の要素が削除されています。
結論
v-forディレクティブを使用する場合は、Vue.jsが要素を正しく認識できるよう、一意の値をkey属性に指定しましょう!
【エンジニア募集中】フルリモートも◎(リモート率85.7%)、平均残業8時間、年休124日以上、有給取得率90% etc. 詳細はこちらから>