Vueのprops・emits・slotsの使い分け|親子コンポーネント連携

プログラミング

※ 当ブログ「日々是事始め(コレコト)」はプロモーションを含みます。

コンポーネントを部品に分けると、次は「部品どうしをどうつなぐか」が問題になります。親から子へデータを渡したい、子で起きたクリックを親で受け取りたい、子の中身を親から差し替えたい——これを担うのが props・emits・slots の3つです。最初は似ていて混乱しましたが、向きと役割で整理すると一気にスッキリしました。

※ 学習用に調べた内容を個人的にまとめたものです。文章は AI の補助を受けて作成しています。


3つの役割を「向き」で覚える

機能向き役割
props親 → 子親から子へデータを渡す
emits子 → 親子から親へイベントを通知する
slots親 → 子親から子へ表示内容(HTML)を差し込む

「データを渡す=props」「イベントを返す=emits」「見た目を差し込む=slots」。この対応だけ押さえれば十分です。


props:親から子へデータを渡す

子コンポーネント側で defineProps を使って「受け取る値」を宣言します。<script setup> なら型引数で型も一緒に決められます。

<!-- 子: MyButton.vue -->
<script setup lang="ts">
const props = defineProps<{
  label: string
  disabled?: boolean
}>()
</script>

<template>
  <button :disabled="props.disabled">{{ props.label }}</button>
</template>
<!-- 親から使う -->
<MyButton label="保存する" :disabled="isSaving" />

文字列はそのまま label="保存する"、変数や真偽値は :disabled="isSaving" のように :v-bind)を付けて渡します。


emits:子から親へイベントを通知する

子で起きた出来事(クリックなど)を親に知らせるのが emits。子で defineEmits を宣言し、emit('イベント名') で発火します。

<!-- 子: MyButton.vue -->
<script setup lang="ts">
const emit = defineEmits<{
  click: []
}>()
</script>

<template>
  <button @click="emit('click')">押す</button>
</template>
<!-- 親で受け取る -->
<MyButton @click="onClick" />

親は @click="onClick" で子のイベントを受け取ります。値を一緒に渡したいときは emit('submit', 入力値) のように第2引数に乗せます。


slots:親から子へ表示を差し込む

「枠は子が用意して、中身は親が決めたい」ときに使うのが slots。子に <slot /> という差し込み口を置きます。

<!-- 子: CardBox.vue -->
<template>
  <div class="card">
    <slot />  <!-- ここに親の中身が入る -->
  </div>
</template>
<!-- 親から使う -->
<CardBox>
  <h2>お知らせ</h2>
  <p>好きなHTMLを差し込めます</p>
</CardBox>

枠(カードの見た目)は使い回しつつ、中身だけ場所ごとに変えられます。見出し・本文など複数の差し込み口が欲しいときは「名前付きスロット」も使えます。


最重要の落とし穴:props は子で書き換えない

Vue のデータの流れは「親 → 子」の一方向が原則です。子が受け取った props を子の中で直接書き換えるのは NG。値を変えたいときは、emits で親に「変えてほしい」と通知し、実際の変更は親が行うのが基本形です。

  • ❌ 子で props.value = ... と直接書き換える
  • ✅ 子で emit('update', 新しい値) → 親が状態を更新する

入力欄でよく使う v-model は、この「props で渡して emits で返す」パターンをまとめた便利な仕組みです。まずは一方向の流れを崩さない、と覚えておけば大きな事故は防げます。



もっと体系的に学ぶなら(書籍)

この記事はシリーズの一部です。TypeScript前提で Composition API・Pinia・Vue Router・テストまで一冊で体系的に学びたい方には、内容がそのまま重なる次の本がおすすめです。

次に読む

Vue Routerでページ遷移を作る|一覧・詳細・登録・編集の基本
※ 当ブログ「日々是事始め(コレコト)」はプロモーションを含みます。コンポーネントで画面の部品は作れるようになっても、「一覧ページから詳細ページへ移動する」ようなページの切り替えはどうやるのか、最初は分かりませんでした。Vue で作る SP...
Vue 3を体系的に学ぶロードマップ|初心者がリアクティブ・REST API・Swagger連携・Vuetifyまで理解する手順
※ 当ブログ「日々是事始め(コレコト)」はプロモーションを含みます。Vue 3 を学び始めたとき、私がいちばん困ったのは「何から手をつければいいのか分からない」ことでした。リアクティブ、Composition API、Vue Router、...

PR

Back to top
タイトルとURLをコピーしました