【Vue.js】子コンポーネントから親コンポーネントのデータを変更する方法【emit】
いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。
Vue.js において、 emit を使って、子コンポーネントから親コンポーネントのデータを変更する方法について、記事にしました
子コンポーネントから親コンポーネントのデータを変更する方法
今回は、親コンポーネントにあるcount
というデータを、子コンポーネントから変更します。
親コンポーネント
<template>
<ChildrenComponent @custom-event="handleEvent" :count="count" />
</template>
<script setup>
import { ref } from "vue"
const count = ref(0)
const handleEvent = () => {
count.value++
}
</script>
子コンポーネント
親で、@custom-event
と書いているので、custom-event という名前で emit できます
<template>
<div>
<button @click.stop="triggerEvent">押すとcountが増える</button>
<div>Count: {{ count }}</div>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from "vue"
// propsの定義
const props = defineProps({
count: Number,
})
// emitの定義
const emit = defineEmits(["custom-event"])
const triggerEvent = () => {
emit("custom-event")
}
</script>
emit とは?
Vue.js の emit は、子コンポーネントから親コンポーネントにイベントを送信する仕組みです。
ようするに親コンポーネントで定義したイベントを、子コンポーネントで使用することができます。
親から子へのデータ伝達は props を使って行いますが、子コンポーネントから親コンポーネントのデータを直接書き換えることは NG とされているため、この emit を使って親のイベントを使用して親のデータを書き換えるのが今回やったこととなります。
引数を使う方法
親コンポーネント
<template>
<ChildrenComponent @custom-event="handleEvent" :count="count" />
</template>
<script setup>
import { ref } from "vue"
const count = ref(0)
const handleEvent = increment => {
count.value += increment
}
</script>
違いは、handleEvent
のところに引数を使うように書いたのみです。
子コンポーネント
<template>
<div>
<button @click.stop="triggerEvent(1)">押すとcountが1増える</button>
<button @click.stop="triggerEvent(2)">押すとcountが2増える</button>
<button @click.stop="triggerEvent(3)">押すとcountが3増える</button>
<div>Count: {{ count }}</div>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from "vue"
// propsの定義
const props = defineProps({
count: Number,
})
// emitの定義
const emit = defineEmits(["custom-event"])
const triggerEvent = increment => {
emit("custom-event", increment)
}
</script>
違いは、triggerEvent
の関数と、ボタンのところに引数を付けています。
以下のようにイベント名の後に引数を書くことができます。
emit("custom-event", increment)
引数を複数渡したい時
以下のように、追加して書くことで渡すことができます。
const triggerEvent = (increment, decrement) => {
emit("custom-event", increment, decrement)
}
オブジェクトして渡すのも考えられます。
const triggerEvent = (increment, decrement) => {
const obj = {
increment: increment,
decrement: decrement,
}
emit("custom-event", obj)
}
状況によってお好みで使いましょう。
Vue 2 のとき
Vue 2 では、子コンポーネントから親コンポーネントにデータを渡す際、$emit
メソッドを使用します。
Vue 3 と異なり、setup 関数や Composition API がないため、通常のオプション API を使用して実装します。
親コンポーネントでイベントリスナーを定義し、子コンポーネントで$emit
を使用してイベントを発火させ、親コンポーネントで受け取ったデータを使って処理を行います。
親コンポーネント
<template>
<children-component
@custom-event="handleEvent"
:count="count"
></children-component>
</template>
<script>
export default {
data() {
return {
count: 0,
}
},
methods: {
handleEvent() {
this.count++
},
},
}
</script>
子コンポーネント
<template>
<div>
<button @click="$emit('custom-event')">押すとcountが増える</button>
<div>Count: {{ count }}</div>
</div>
</template>
<script>
export default {
props: {
count: {
type: Number,
required: true,
},
},
}
</script>
このように Vue 2 では、オプション API で methods や data を定義して親子間のデータのやり取りを行います。
まとめ
子コンポーネントから親コンポーネントのデータを更新する方法でし た。
ほぼ emit の話になりました。
もっと深く知りたい方は、ドキュメントを見ると面白いんじゃないでしょうか