ホーム > Vue > 【Vue.js】子コンポーネントから親コンポーネントのデータを変更する方法【emit】
Vue

【Vue.js】子コンポーネントから親コンポーネントのデータを変更する方法【emit】

いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。

⇨ Vue 記事の目次はこちら

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 の話になりました。

もっと深く知りたい方は、ドキュメントを見ると面白いんじゃないでしょうか

Vue.js - コンポーネントのイベント

フィードバックのお願い
この記事のフィードバックがありましたらYoutubeの適当な動画にコメントしていただいたり、お問い合わせからご連絡ください。