owned mediaウェブ制作に役立つコンテンツを発信中!

Vue.jsで$emitとv-onを使った子から親のコンポーネントにおける値の受け渡し

Vue.jsにおいてはコンポーネント間で値の受け渡しをする場面が多々あります。過去記事「propsで親コンポーネント内から子コンポーネントへ値やデータを渡す」でも紹介しているようにpropsを使って親から子へと流れるように値を渡していきます。ただし、この方法は親から子コンポーネントへの値受け渡しに使えるもので、逆の子から親コンポーネントへの値受け渡しには使えません。   そこで今回は子コンポーネントから親コンポーネントへの値受け渡しの方法をまとめていきたいと思います。stateを使って値を取得する方法もありますが、ここでは「$emit」と「v-on」ディレクティブを使った密結合になる方法になります。  
親コンポーネントから子コンポーネントのイベントをハンドリング
今回は「$emit」と「v-on」を使って子コンポーネントのイベントを親コンポーネント側でハンドリングすることで値の受け渡しを完了させます。まずは、そのイベントハンドリングから見ていきたいと思います。今回は下記のように親コンポーネントを用意しました。 【ComponentParent.vue】※一部抜粋
<template>
 <div>
  <component-child></component-child>
 </div>
</template>

<script>
 import ComponentChild from '../components/ComponentChild.vue' 
 export default {
  name: 'ComponentParent',
  components: {
   ComponentChild
  },
 }
</script>
  子コンポーネントを読み込んでいるだけのシンプルな構成ですね。ここから子コンポーネントのイベントをハンドリングするために処理を加えていきます。まず、テンプレート内に「v-on」ディレクティブでイベントを設定します。下記では省略形の@を使った記法で進めていきます。ここで設定するイベントですが、子コンポーネント側で独自に定義するイベントを設定します。そしてこのイベントで発火される関数を親コンポーネントの「methods」に定義し呼び出されるようにしておきます。 【ComponentParent.vue】※一部抜粋
<template>
 <div>
  <component-child @child-event="parentMethod"></component-child>
 </div>
</template>

<script>
 import ComponentChild from '../components/ComponentChild.vue' 
 export default {
  name: 'ComponentParent',
  components: {
   ComponentChild
  },
  methods: {
   parentMethod() {
    console.log('子コンポーネントのイベントを検知しました');
   }
  }
 }
</script>
  上記ではコンソールで子コンポーネントに設定しているイベントを発火した時にメッセージが確認できるような処理を記述しています。これで親コンポーネント側での処理は完了です。続いて子コンポーネント側での処理を見ていきます。 【ComponentChild.vue】※一部抜粋
<template>
 <div>
 </div>
</templete>

<script>
 export default {
  name: 'ComponentChild',
  created() {
   this.triggerEvent();
  },
  methods: {
   triggerEvent() {
    this.$emit('child-event');
   }
  }
 }
</script>
  ここで注目すべきポイントは、methodsで定義されている「$emit()」の部分です。これを実行することで、引数に指定したイベントを発火させることができます。この引数に入る値は、先ほど親コンポーネント側で設定したイベント名が入ります。そして、任意のタイミングでmethodsに定義した関数が実行されるようにしておきます。   こうすることで、親コンポーネント側で、子コンポーネントのイベントハンドリングできるようになり、親コンポーネントで定義した処理を実行することができます。 【console】
"子コンポーネントのイベントを検知しました"
  上記コードでコンソールを確認してみると、このようにメッセージが表示され、子コンポーネントのイベントで親コンポーネントの処理が行われているのが確認できます。  
イベントハンドリングで子から親へ値を受け渡す
先ほどの子コンポーネントから親コンポーネントへのイベントハンドリングを使うことで、子から親コンポーネントへ値を受け渡すことができます。値を受け渡すために、先ほどのコードへ次のように一部追記をしました。まずは親コンポーネントからです。 【ComponentParent.vue】※一部抜粋
<template>
 <div>
  <component-child @child-event="parentMethod"></component-child>
  <p>
   子コンポーネントから受け取った値は『{{ messsage }}』です
  </p>
 </div>
</template>

<script>
 import ComponentChild from '../components/ComponentChild.vue' 
 export default {
  name: 'ComponentParent',
  components: {
   ComponentChild
  },
  data() {
   return {
    messsage: ''
   }
  },
  methods: {
   parentMethod(payload) {
    this.message = payload;
   }
  }
 }
</script>
  親コンポーネント側には、テンプレート内に値が受け渡されたのを確認するための出力部分を設けています。出力されるデータは、親コンポーネントの「data」で定義しておきます。そして、このdataで定義した値には、子コンポーネントから受け取った値を、子コンポーネントのイベントで呼び出すメソッドの引数に入るようにすることで、その引数で更新できるようにしておきます。ここではpayloadという名前で引数を入れています。   この時点では初期値は空なので次のように何も表示されないようになっています。 Vue.jsで$emitとv-onを使った子から親のコンポーネントにおける値の受け渡し   そして子コンポーネントを見ていきます。まず、親コンポーネントに受け渡すための値を「data」で同じく定義しておきます。ここには値をそのまま入れておきます。そして、先ほど説明した「$emit()」の第二引数に受け渡したい値を指定しておきます。つまり今回のケースでは、子コンポーネントのdataで定義した値が入ります。最後に任意のタイミングで$emitを定義したメソッドを実行します。 【ComponentChild.vue】※一部抜粋
<template>
 <div>
 </div>
</templete>

<script>
 export default {
  name: 'ComponentChild',
  data() {
   return {
    textData: 'Hello Vue!!'
   }
  },
  created() {
   this.triggerEvent();
  },
  methods: {
   triggerEvent() {
    this.$emit('child-event', this.textData);
   }
  }
 }
</script>
  こうすることで、子コンポーネントで設定したイベントが発火されると同時に、子コンポーネントから親コンポーネントへの値の受け渡しが行われ、親コンポーネント側で値を取り扱うことができるようになります。実際に試してみるとこのように表示されているのが確認できます。   console.logなどで子コンポーネントから値を受け取っているのも確認できますね。 Vue.jsで$emitとv-onを使った子から親のコンポーネントにおける値の受け渡し  
  今回は子コンポーネントから親コンポーネントへの値を受け渡す方法についてまとめていきました。親から子への値受け渡しと異なり、少しややこしいですが覚えておくと便利ですね。ただし、あまり複雑になりすぎるとコンポーネント間の関係が密結合になるので、影響範囲が大きくなる場合にはstateで管理する方が良いのではないでしょうか。
  • はてなブックマーク
  • Pocket
  • Linkedin
  • Feedly

この記事を書いた人

Twitter

sponserd

    keyword search

    recent posts

    • Twitter
    • Github
    contact usscroll to top
      • Facebook
      • Twitter
      • Github
      • Instagram