
Vue.js ルーティング演習問題
基本概念まとめ 1. ルーティングの基本設定 2. ナビゲーションガード 3. 動的ルーティング 演習問題(全24問) 初級問題(6問) 基本ルーティング ナビ […]
Vue.jsにおいて、Props(プロパティ)は親コンポーネントから子コンポーネントへデータを渡すための仕組みです。Reactや他のフレームワークにも類似の概念がありますが、VueのPropsシステムは特にシンプルで直感的に使用できるように設計されています。
[親コンポーネント]
│
↓ (propsとしてデータを渡す)
[子コンポーネント]
このデータフローは一方向(親→子)に限定されており、これによりアプリケーションのデータフローが予測可能で理解しやすくなります。
親コンポーネントでデータを定義し、子コンポーネントに渡します。
<template>
<div>
<!-- 子コンポーネントにmessageデータを渡す -->
<ChildComponent :message="parentMessage" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: '親からのメッセージ'
}
}
}
</script>
子コンポーネントはprops
オプションで受け取るデータを宣言します。
<template>
<div>
<!-- 親から受け取ったmessageを表示 -->
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
props: ['message'] // 親からmessage propを受け取る
}
</script>
Propsには型指定やバリデーションを設定できます。
export default {
props: {
// 基本的な型チェック
age: Number,
// 複数の型を許可
userId: [String, Number],
// 必須フラグとデフォルト値
username: {
type: String,
required: true,
default: '匿名ユーザー'
},
// カスタムバリデーター
email: {
type: String,
validator: value => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
}
}
}
}
オブジェクトや配列もpropsとして渡せます。
<!-- 親コンポーネント -->
<template>
<ChildComponent :user-info="userData" :items="itemList" />
</template>
<script>
export default {
data() {
return {
userData: {
name: '山田太郎',
age: 30
},
itemList: ['アイテム1', 'アイテム2', 'アイテム3']
}
}
}
</script>
<!-- 子コンポーネント -->
<script>
export default {
props: {
userInfo: Object,
items: Array
}
}
</script>
v-bindを使って動的にpropsを渡せます。
<template>
<div>
<input v-model="dynamicMessage" />
<ChildComponent :message="dynamicMessage" />
</div>
</template>
<script>
export default {
data() {
return {
dynamicMessage: ''
}
}
}
</script>
Vueでは以下の命名規則が推奨されます:
// 子コンポーネント
export default {
props: ['userName', 'isActive']
}
// 親コンポーネント
<template>
<ChildComponent
:user-name="name"
:is-active="active"
/>
</template>
propsとして明示的に宣言されていない属性は、子コンポーネントのルート要素に自動的に適用されます。
// 親コンポーネント
<ChildComponent class="child-style" data-test="test" />
// 子コンポーネントのレンダリング結果
<div class="child-style" data-test="test">
<!-- 子コンポーネントの内容 -->
</div>
オブジェクトを使ってまとめてpropsを渡せます。
<template>
<ChildComponent v-bind="userProps" />
</template>
<script>
export default {
data() {
return {
userProps: {
name: '佐藤花子',
age: 25,
email: 'sato@example.com'
}
}
}
}
</script>
親のメソッドを子に渡すことも可能です。
<!-- 親コンポーネント -->
<template>
<ChildComponent :formatter="formatName" />
</template>
<script>
export default {
methods: {
formatName(name) {
return name.toUpperCase()
}
}
}
</script>
<!-- 子コンポーネント -->
<script>
export default {
props: {
formatter: Function
},
methods: {
processName(name) {
return this.formatter(name)
}
}
}
</script>
// 悪い例
this.message = '新しい値' // 警告が発生
// 良い例
// 親コンポーネントにイベントを発行して変更を依頼
this.$emit('update:message', '新しい値')
export default {
props: ['initialCount'],
data() {
return {
count: this.initialCount // propsから初期値を設定
}
}
}
export default {
props: ['config'],
watch: {
config: {
deep: true, // ネストされた変更も監視
handler(newVal) {
console.log('configが変更されました', newVal)
}
}
}
}
<!-- 親コンポーネント -->
<template>
<div>
<ProductCard
v-for="product in products"
:key="product.id"
:product="product"
/>
</div>
</template>
<script>
export default {
data() {
return {
products: [
{ id: 1, name: 'ノートパソコン', price: 120000, stock: 5 },
{ id: 2, name: 'スマートフォン', price: 80000, stock: 10 }
]
}
}
}
</script>
<!-- 子コンポーネント (ProductCard.vue) -->
<template>
<div class="product-card">
<h3>{{ product.name }}</h3>
<p>価格: {{ product.price.toLocaleString() }}円</p>
<p :class="{ 'low-stock': product.stock < 3 }">
在庫: {{ product.stock }}個
</p>
</div>
</template>
<script>
export default {
props: {
product: {
type: Object,
required: true,
validator: product => {
return (
typeof product.id === 'number' &&
typeof product.name === 'string' &&
product.price > 0
)
}
}
}
}
</script>
<style>
.product-card {
border: 1px solid #ddd;
padding: 16px;
margin: 8px;
border-radius: 4px;
}
.low-stock {
color: red;
font-weight: bold;
}
</style>
v-once
ディレクティブを使用<template>
<div v-once>
{{ staticMessage }}
</div>
</template>
export default {
props: ['rawDate'],
computed: {
formattedDate() {
return new Date(this.rawDate).toLocaleDateString()
}
}
}
このガイドでVue.jsのpropsシステムの基本から実践的な使い方までを網羅的に理解できたはずです。propsを適切に使用することで、コンポーネント間のデータフローを明確にし、保守性の高いアプリケーションを構築できます。