了解です!ではご要望どおり、見出しの先頭にわかりやすい記号を付けて、続きを書いていきます。


第2章 2.2 emitをdefineEmitsで型安全に書き換える

ここでは、イベント(emit)の型安全な書き方について、

もう少し掘り下げて詳しく説明します。


【変換前】クラスコンポーネントでのemit定義

<template>
  <!-- ボタンをクリックするとincrementメソッドが発火 -->
  <button @click="increment">Increment</button>
</template>

<script lang="ts">
// 必要なものをインポート
import Vue from 'vue';
import Component from 'vue-class-component';
import { Emit } from 'vue-property-decorator';

@Component
// クラスコンポーネントの定義
export default class ChildComponent extends Vue {
  // incrementイベントをemitする(返り値はemitされるpayloadになる)
  @Emit('increment')
  increment() {
    // emitするだけなので中身は空
  }
}
</script>


【変換後】Composition APIでのemit定義(型安全)

<template>
  <!-- ボタンをクリックするとincrement関数が発火 -->
  <button @click="increment">Increment</button>
</template>

<script lang="ts" setup>
// emitsの型を定義する(どのイベント名で、どの型のpayloadを送るか)
const emit = defineEmits<{
  (event: 'increment'): void;
}>();

// incrementイベントをemitする関数(payloadなし)
function increment() {
  emit('increment');
}
</script>


【型安全のポイント】

項目 説明
イベント名 'increment' という固定文字列
payload型 今回は void (つまり何も渡さない)
型の場所 defineEmits<...> 内に書く
型エラー防止 イベント名やpayloadのミスが即座に検出される

◼️ 【もし payload(値)をemitしたい場合】

例:increment イベントで number を渡したいとき

<script lang="ts" setup>
// イベント定義時にpayloadの型(number)を指定
const emit = defineEmits<{
  (event: 'increment', payload: number): void;
}>();

// emit時にnumber型の値を渡す
function increment() {
  emit('increment', 1); // 1を渡す
}
</script>


【ポイント】クラス時代との違いまとめ