Vueで「<template>cannot be keyed. Place the key on real elements instead.」になった場合の解決策

Vue のエラー

以下のコードは、下記のエラーとなります。

<table>
    <thead>
        <tr>
            <th>id</th>
            <th>name</th>
        </tr>
    </thead>
    <tbody>
        <template v-for="user in users" :key="user.id">
            <user-row :user="user"></user-row>
        </template>
    </tbody>
</table>
<template> cannot be keyed. Place the key on real elements instead.

template に対して :key を設定していることによって当該エラーは発生しています。

タグを template ではなく div などに変更すればエラーも出ずに解決なのですが、レイアウトが崩れるという問題がある為、どうしても template が使用したい状況です。

そのような場合には template タグではなく、その配下のタグに対して :key を設定します。

<table>
    <thead>
        <tr>
            <th>id</th>
            <th>name</th>
        </tr>
    </thead>
    <tbody>
        <template v-for="user in users">
            <user-row :user="user" :key="user.id"></user-row>
        </template>
    </tbody>
</table>

これでエラーは解消します。

:key は必要なのか?

余談ですが、:key を設定しなかったとしても、例えば Visual Studio Code だと下記メッセージが表示されるだけでエラーにはなりません。

Custom elements in iteration require 'v-bind:key' directives.

エラーにはなりませんが、axios などのHTTPクライアントで users を再度 get したとしても、更新されるのは data の users(user) だけで、コンポーネント側の props の user は変化しません。

key は必ず設定すべきです。

key 特別属性は、主に古いリストの代わりにノードの新しいリストを差分算出する VNode を識別するために Vue の仮想 DOM アルゴリズムに対するヒントとして使用されます。

キーがない場合、Vue は要素の移動を最小限に抑えるアルゴリズムを使用し、可能な限りその場で同じタイプの要素にパッチ適用/再利用しようとします。

キーがある場合は、キーの順序の変化に基づいて要素を並べ替え、そして、もはや存在しないキーを持つ要素は常に削除/破棄されます。

同じ共通の親を持つ子は、一意なキーを持っていなければなりません。重複するキーはエラーを描画する原因になります。

API | Vue.js

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)