基礎からメモ: Vue.js CH2-p70 リストデータの表示と更新
リストデータの表示
リストデータを使って要素を繰り返し表示するには、li
タグに対してv-for
を使う。
基本になる構文は、
<li v-for="変数名 in リスト">
[index10.html]
<div id="app"> <ul> <li v-for="item in list" v-bind:key="item.id"> ID: {{ item.id }} {{ item.name }} HP: {{ item.hp }} </li> </ul> </div>
[main10.js]
var app = new Vue({ el: '#app', data: { list: [ { id: 1, name: 'スライム', hp: 100 }, { id: 2, name: 'ゴブリン', hp: 200 }, { id: 3, name: 'ドラゴン', hp: 500 }, ] }, })
表示結果
- ID: 1 スライム HP: 100
- ID: 2 ゴブリン HP: 200
- ID: 3 ドラゴン HP: 500
配列の表示
リストデータは各要素にユニークなキーを持っていることが望ましいので、できればこのようなオブジェクトを要素にした配列が最適。ただしただの配列でも利用はできる。
<ol> <li v-for="item in array"> {{ item }} </li> </ol>
data: { array: [ 'インド', '中国', 'パキスタン'], }
- インド
- 中国
- パキスタン
インデックスの受取り
配列のインデックスを利用するには、繰り返しの変数部分を括弧で囲み次のように記述する。
<ul> <li v-for="(item, index) in array"> {{ index }} : {{ item }} </li> </ul>
- 0 : インド
- 1 : 中国
- 2 : パキスタン
オブジェクトのキーの受取り
オブジェクトのキーは変数部分にインデックスも含めた3つの引数を持たせた上で、第二引数で受ける。
<li v-for(値, キー, インデックス) in オブジェクト>
data: { student: { id: 1, name: "Ammanda", age: 20, job: "OL"} }
<ul> <li v-for="(prop, key, index) in student"> [{{ index }}] {{ key }} / {{ prop }} </li> </ul>
表示結果
- [0] id / 1
- [1] name / Ammanda
- [2] age / 20
- [3] job / OL
オブジェクトデータのインデックスの順序はJavaScriptエンジンの実装によって違うので、必ずしもこの順にはならない。
少し複雑になるが最初のリストデータを使って表のセルにkey:value
形式で書き出してみる。
<table> <tr v-for="(item, index) in list" v-bind:key="item.id"> <td>{{ index }}</td> <template v-for="(val, key, index) in item"> <td>{{ key }}: {{ val }}</td> </template> </tr> </table>
表示結果
0 | id: 1 | name: スライム | hp: 100 |
1 | id: 2 | name: ゴブリン | hp: 200 |
2 | id: 3 | name: ドラゴン | hp: 500 |
キーの役割り
繰り返し処理の中にあったv-bind:key="item.id"
は、要素の識別と効率的なレンダリングのために、リストの各要素にユニークなkey
属性を付与するもの。key
とする値は各要素にユニークである必要があるので、配列のインデックスのような変更される可能性がある値は適さない。
その意味で、リストデータはそれぞれの配列要素が固有のIDを持てるように、オブジェクトデータの配列とするのが最適。
list: [ { id: 1, name: 'スライム', hp: 100 }, { id: 2, name: 'ゴブリン', hp: 200 }, { id: 3, name: 'ドラゴン', hp: 500 }, ]
ユニークなkey
属性を付与することで個別の要素をVue側が識別できるようになり、要素の削除や変更の際、変更のあった要素のみを更新するようになる。ユニークなkey
属性が無く個別要素の識別が難しい場合は、同列の要素全てを再描画するのでレンダリング効率が落ちる。
なお、同じ親要素内で2度以上同じリストにv-for
を使うと、キーの重複ができないためエラーになる。
<ul> <li v-for="item in list" v-bind:key="item.id">{{ item.name }}</li> <li v-for="item in list" v-bind:key="item.id">{{ item.hp }}</li> </ul>
コンソールに次のエラーが出る。
vue.js:597 [Vue warn]: Duplicate keys detected: '1'. This may cause an update error. ...........................................
- リストデータを使って要素を繰り返し表示するには、繰り返すタグに対して
v-for
を使う。- リストの各要素にユニークな
key
属性を付与することで、要素の識別と効率的なレンダリングが可能になる。