Vue 3 defineEmits
の基本と活用方法まとめ
Vue 3 の Composition API と共に登場した <script setup>
構文は、簡潔で直感的な記述を可能にしました。この記事では、その中でも子コンポーネントから親コンポーネントへイベントを発行するための仕組みである defineEmits
について解説します。
✨ defineEmits
とは
defineEmits
は、Vue 3のコンポーネントの中で「親コンポーネントにイベントを通知する」ための関数です。
const emit = defineEmits(['custom-event']);
上記のように使うと、emit('custom-event')
で親にイベントを発行できるようになります。
✅ 基本な使い方
【子コンポーネント】MyButton.vue
<script setup>
const emit = defineEmits(['click']);
const handleClick = () => {
emit('click');
};
</script>
<template>
<button @click="handleClick">Click me</button>
</template>
【親コンポーネント】App.vue
<template>
<MyButton @click="onChildClick" />
</template>
<script setup>
import MyButton from './MyButton.vue';
const onChildClick = () => {
alert('Button clicked!');
};
</script>
子が emit した click
イベントを、親が @click
で受け取っています。
▶ v-model
との連携
Vue 3 で v-model
を使用する場合、子コンポーネントは modelValue
を prop として受け取り、update:modelValue
を emit する必要があります。
【例】InputComponent.vue
<script setup>
const props = defineProps({ modelValue: String });
const emit = defineEmits(['update:modelValue']);
const updateValue = (e) => {
emit('update:modelValue', e.target.value);
};
</script>
<template>
<input :value="modelValue" @input="updateValue" />
</template>
【使用側】App.vue
<template>
<InputComponent v-model="text" />
</template>
<script setup>
import InputComponent from './InputComponent.vue';
import { ref } from 'vue';
const text = ref('');
</script>
🌟 TypeScript で型指定する
const emit = defineEmits<{
(e: 'submit', payload: { name: string }): void;
}>();
emit('submit', { name: 'John' });
これによって、間違った型のペイロードを渡した場合は TypeScript が検出してくれます。
⚠ よくある間違い
❌ @click="emit('click')"
はダメ
- これはテンプレートのレンダリング時に実行されてしまいます。
- 正しくは
@click="() => emit('click')"
または@click="handleClick"
にしましょう。