こんなデータを表示したい
以下のリスト一つ一つをvueコンポーネントとして表示
list: [
{
id: 1,
name: "リスト1"
},
{
id: 2,
name: "リスト2"
}
]
子コンポーネント
props
で親コンポーネントから渡された値を画面に表示するだけのコンポーネントです。
ListComponent.vue
<template>
<div>{{ target }}</div>
</template>
<script>
export default {
props: {
target: {
type: Object, // 型がObjectである
required: true // 必須のプロパティである
}
}
};
</script>
ポイント
何も考えずにprops
に値を渡すと、以下のようになると思います。
<script>
export default {
props: [target]
};
</script>
この場合、以下のようなデメリットがあります。
- 値がundefinedのときに気づきにくい
- 変数にどんな値が入るか推測しづらい
props
には、基本的にバリデーションを行いましょう。
バリデーションには
- 型
- 必須かどうか
- デフォルト値
などを指定することができます。
ここである程度バリデーションをかけておくことで、エラーの発生原因などを特定しやすくなります。
親コンポーネント
オブジェクトのリストをfor文で全て表示します。
Parent.vue
<template>
<div>
<list-component v-for="item in list" :key="item.id" :target="item" />
</div>
</template>
<script>
export default {
components: {
ListComponent
},
data: function() {
return {
list: [{ id: 1, name: "リスト1" }, { id: 2, name: "リスト2" }]
};
}
};
</script>
ポイント
-
v-for
はコンポーネントタグの中で書ける - listの中身を一意に判定できる
key
を指定する - オブジェクトのまま子コンポーネントに渡すことができる
1. v-forはコンポーネントタグの中で書ける
<template>
<div>
<div v-for="item in list"> <!-- v-forのためだけのタグで囲う必要はない -->
<list-component :target="item" />
</div>
</div>
</template>
2. listの中身を一意に判定できるkey
を指定する
key
が未指定でもエラー出ませんが、公式ドキュメントでも推奨されています。
リストに変更があった場合
- 'key`未指定:リストが全件更新、再描画してしまう
- 'key`指定:変更があったリストの中身を検知し、それだけを更新
3. オブジェクトのまま子コンポーネントに渡すことができる
オブジェクトの中身を以下のようにそれぞれ渡すことができますが、
オブジェクト内部の情報を全て使うのであれば、オブジェクトごと子コンポーネントに渡しましょう。
<template>
<div>
<list-component v-for="item in list" :key="item.id"
:id="item.id"
:name="item.name"
/>
</div>
</template>
あとがき
よくあるケース&忘れそうなのでまとめておきました。