Vue.jsのemit
とは何か?
親コンポーネントから子コンポーネントに対して値を渡すpropsに対し、
emitは子コンポーネントでボタンが押されたり、テキストボックスの変更などが発生したときに親コンポーネントに伝えることができる。
また、子コンポーネントから親コンポーネントにデータを渡したいときにも使われる。
なぜemitが必要なのか
→親コンポーネントから渡されたpropsは子コンポーネントの中では読み取り専用であり、変更することができないから。
例えば、子コンポーネントの以下のコードでsetNewCount関数が発火されるとエラーが起こる。
const props = defineProps({
count: Number
})
const setNewCount = () => {
// 読み取り専用のcountを更新しに行くのでエラーが起こる。
props.count++
}
これは、Vue.jsの設計上の仕様である。親→子への単一方向のデータ渡ししかできないようにすることで、データフローの複雑化を防止してシンプルになるようにしている。
では、親コンポーネントから渡されたpropsを子コンポーネント内のイベントで更新するにはどうすればいいのか。それを解決するのがemitである。
emitを使ってみよう!
今回はemitを使って、子コンポーネント内のボタンを押すと、親コンポーネントのリアクティブ変数「count」が更新されるサンプルコードを作成しました。
- 親コンポーネント
vue.js
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
// カウントを管理するリアクティブ変数
const count = ref(0);
// 子コンポーネントからのイベントをハンドリングするメソッド
const setNewCount = (newCount) => {
count.value = newCount;
};
</script>
<template>
<div>
<p>カウント: {{ count }}</p>
<ChildComponent :count="count" @set:newCount="setNewCount" />
</div>
</template>
- 子コンポーネント
vue.js
<script setup>
import { ref } from 'vue';
// 親コンポーネントから渡されるカウント
const props = defineProps({
count: Number
})
// 子コンポーネントのカウントを管理するリアクティブ変数
const childCount = ref(props.count);
const emit = defineEmits(['set:newCount'])
// 子コンポーネントのカウントを増やすメソッド
const setNewCount = () => {
childCount.value++;
// 親コンポーネントにイベントを発火し、新しいカウントを通知
emit('set:newCount', childCount.value);
};
</script>
<template>
<div>
<p>子コンポーネントのカウント: {{ count }}</p>
<button @click="setNewCount">子コンポーネントのカウントを増やす</button>
</div>
</template>