Vueの中でv-forを使っている処理を見ると、v-forと合わせて「key」が記載されていることがあります。
あるいは、Vueでv-forを使おうとすると、次のようなエラーが表示されることがあります。
[require-v-for-key] Elements in iteration expect to have 'v-bind:key' directives.eslint-plugin-vue
ここでは、v-forと一緒に使われているkeyの意味や目的、必要性と、上記のエラーの原因と対処法についてまとめています。
エラーの内容と原因
[require-v-for-key] Elements in iteration expect to have 'v-bind:key' directives.eslint-plugin-vue
このエラーの内容は、v-forには「v-bind:key」が必要ですというものです。
keyを設定する理由は「Vueの裏側の処理を助けるため」です。自分が記述する処理の中で直接使用するわけではありません。
Vueでv-forを使う時は記述する決まりということです。
エラー発生の実例
例えば、以下のように配列array:[ 'xxx', 'yyy', 'zzz' ]
の各要素をv-forで一つづつ表示しようとすると発生します。
<template>
<ul v-for="arr in array">
<li>{{ arr }}</li>
</ul>
</template>
<script>
export default {
data(){
return {
array: [
'xxx',
'yyy',
'zzz'
]
}
}
}
</script>
<style scoped>
</style>
以下のように、v-forにkeyが設定されていません。
<ul v-for="arr in array">
v-forにkeyが必要な理由
なぜkeyが必要かというと、forで表示した処理に対して要素を並べ替えする場合に、Vueがこのキーを参照するためです。
対処法
対処法はv-forに「v-bind:key」(または省略形の「:key」)を記述することです。
その際注意点が1つあります。それは設置するkeyの値が要素ごとに一意(ユニーク)になることです。
主な記述方法には次の2つがあります。
インデックス番号を指定する
記述方法
v-forでは要素を抜き出すときに、各要素のインデックス番号も合わせて抜き出すことができます。
それを:keyの値として指定するとエラーが解消します。
v-for="(要素を入れる変数名, インデックス番号を入れる変数名) in array" :key=インデックス番号を入れる変数名
実例
例えば、以下のように配列array:[ 'xxx', 'yyy', 'zzz' ]
の各要素をv-forで一つづつ表示しようとする場合、各要素を入れる変数を「arr」、各要素のインデックス番号を入れる変数を「index」とします。
v-forを設置しているタグに「:key=index」を設置すればエラーは解消します。
<template>
<ul v-for="(arr, index) in array" :key=index>
<li>{{ arr }}</li>
</ul>
</template>
<script>
export default {
data(){
return {
array: [
'xxx',
'yyy',
'zzz'
]
}
}
}
</script>
<style scoped>
</style>
以下がポイントです。
<ul v-for="(arr, index) in array" :key=index>
ブラウザの表示
ブラウザの表示は以下のようになります。
プロパティ名などを指定する
記述方法
:keyを指定するときに、必ずインデックス番号を使わなければいけないわけではありません。
v-forで回す要素の中に一意の値があればそれを使っても問題ありません。
v-for="要素を入れる変数名 in array" :key=要素を入れる変数名.固有の値を持つプロパティ名
実例
例えば、次のようなusersというデータがあるとします。
users: [
{ id: 1, name: "xxx", age: 11 },
{ id: 2, name: "yyy", age: 22 },
{ id: 3, name: "zzz", age: 22 },
{ id: 4, name: "zzz", age: 11 },
]
この中には各データごとに固有となる値「id」が含まれています。
各要素を「user」という変数名で抜き出したとき、v-forを設置しているタグに「:key=user.id」を設置すればエラーは解消します。
<template>
<ul v-for="user in users" :key=user.id >
<li>ID: {{ user.id }}</li>
<li>名前: {{ user.name }}</li>
<li>年齢: {{ user.age }}</li>
</ul>
</template>
<script>
export default {
data(){
return {
users: [
{ id: 1, name: "xxx", age: 11 },
{ id: 2, name: "yyy", age: 22 },
{ id: 3, name: "zzz", age: 22 },
{ id: 4, name: "zzz", age: 11 },
]
}
}
}
</script>
<style scoped>
</style>
以下がポイントです。
<ul v-for="user in users" :key=user.id >
ブラウザの表示
ブラウザの表示は以下のようになります。
注意点: v-forの中でv-ifを使う場合
v-forの中でv-ifを使う場合は:keyを設定する場所が変わります。
その場合は、v-forを設置しているタグ内ではなく、v-forの下のv-ifを設置しているタグに:keyを設定する必要があります。
v-forに:keyを設置しているのに「[require-v-for-key] Elements in iteration expect to have ‘v-bind:key’ directives.eslint-plugin-vue」というエラーが発生する、、という方は、v-ifの方に:keyを付け替えてみてください。
実例
<template>
<div>
<table>
<template v-for="tr in rows" :key="tr.index">
<tr>
<template v-for="cell in tr.table_cells">
<th v-if="cell.cell_type == 'TH'" :key="cell.index" >
<p></p>
</th>
<td v-else-if="cell.cell_type == 'TD'" :key="cell.index">
<p></p>
</td>
</template>
</tr>
</template>
</table>
</div>
</template>
<th v-if="cell.cell_type == 'TH'" :key="cell.index" >
v-forを設置しているタグの中ではなく、v-ifを設置しているタグの中に「:key」を設定しています。