emit と defineEmits の違い/props と defineProps の違い

emit と defineEmits の違い

用語説明
emit 親コンポーネントに送信できるイベントを定義する
defineEmits定義したイベントを実際に発火(送信)する

使い方

<script setup>
import { ref } from 'vue';

const search = ref('');
const emit = defineEmits(['search']); // ① どんなイベントを送れるか定義

const searchUsers = () => {
    emit('search', search.value); // ② 実際にイベントを発火して親に送る
};
</script>

defineEmits「このコンポーネントでは search というイベントを発火できるよ」 という宣言。
emit('search', search.value);実際に search イベントを発火する処理

props と defineProps の違い

用語説明
defineProps親コンポーネントから受け取る値(props)を定義する
propsdefineProps で定義された値を実際に使うための変数

使い方

<script setup>
const props = defineProps(['label']); // ① 親から受け取るデータを定義
</script>

<template>
  <button>{{ props.label }}</button> <!-- ② props.label を使う -->
</template>

親コンポーネントがこのコンポーネントを使うとき、次のように label を渡せます。

<MyButton label="クリック!" />

この場合、props.label には "クリック!" という値が入ります。

props と emit はどう違う?

emitもpropsと同じように変数のような役割をしていて、対になっていると思っていたのですが、
そうではないということですね!

その理解は 半分正解で、半分違う という感じですね!
確かに propsemit は対になることが多い のですが、「変数のような役割をする」かどうか という点で違いがあります。

項目propsemit
何をする?親から子にデータを渡す子から親にデータを送る
どんなもの?変数のようなデータ関数(トリガー)
いつ使う?受け取ったデータを使いたいときデータを送りたいとき
props.messageemit('sendMessage', 'こんにちは!')

props は「データ」そのもの

props親コンポーネントから渡される値 なので、変数のようなもの です。
子コンポーネント内で props.〇〇 として値を参照できます。

例: props の場合

<script setup>
const props = defineProps(['message']); // 親から受け取るデータ
</script>

<template>
  <p>{{ props.message }}</p>  <!-- ここでデータを表示 -->
</template>

👆 この場合の props.message は「変数」と同じ感覚で使える!

emit は「関数」で、データを送るトリガー

一方 emit関数 であり、親コンポーネントにデータを「渡すための手段」です。
「ボタンを押したら emit でデータを送る」 という動作が一般的です。

例: emit の場合

<script setup>
const emit = defineEmits(['sendMessage']); // "sendMessage" というイベントを定義

const sendData = () => {
    emit('sendMessage', 'こんにちは!'); // ここでデータを送る
};
</script>

<template>
  <button @click="sendData">送信</button>  <!-- クリックで親にデータを送る -->
</template>

この場合の emit('sendMessage', 'こんにちは!') は「関数の呼び出し」!

props と emit は対になっていることが多い

親 → 子 にデータを渡すときは props
子 → 親 にデータを渡すときは emit を使います。

親コンポーネント

<ChildComponent message="こんにちは!" @sendMessage="handleMessage" />

子コンポーネント

<script setup>
const props = defineProps(['message']); // 親から受け取る
const emit = defineEmits(['sendMessage']); // 親に送るイベントを定義

const sendData = () => {
    emit('sendMessage', 'ありがとう!'); // 親にデータを送る
};
</script>

<template>
  <p>{{ props.message }}</p>  <!-- 親から受け取ったデータ -->
  <button @click="sendData">返信する</button>  <!-- 親にデータを送る -->
</template>

このように props でデータを受け取り、emit でデータを送ることが多い!

defineProps は {} で囲み、defineEmits は [] なのはなぜ?

これは、それぞれの役割の違いによるものです。

メソッド形式なぜこの書き方?
defineProps({ ... }){} (オブジェクト)複数の props をキーと型のペアで管理するため
defineEmits(['event1', 'event2'])[] (配列)発火できるイベント名のリストを定義するだけなので
ブログとして載せるときは表を修正した方が良いかも。。。

defineProps({ ... }) の場合

defineProps では オブジェクト形式 ({}) で定義します。
なぜなら、複数のプロパティ(データ)を渡す ことができるからです。

defineProps({
    users: Object,  // users というオブジェクトを受け取る
    isAdmin: Boolean, // isAdmin という真偽値を受け取る
});

props は「どんなデータを受け取るか」の設定なので、キーと型を持つオブジェクトとして定義する。

defineEmits(['search']) の場合

一方で defineEmits発火できるイベント名のリスト を定義するものです。
イベントは キーと値を持つデータではなく、単なる名前(リスト) なので、[] を使います。

defineEmits(['search', 'update']); // search と update というイベントを emit できる

emits は「どんなイベントを発火できるか」のリストなので、配列 [] を使う。

コメント

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