2017/09/14

[Vue.js]Callback vs Emit Events / 子コンポーネントから親のメソッドを実行する方法

Vue.jsにおける親子コンポーネント間でのデータの受け渡しの基本は、Pass Props / Emit Eventsである。親から子へはPropsでデータを渡し、子から親へはEmitでデータを渡す。

そんな面倒なことするより親コンポーネントから子コンポーネントにコールバック関数を渡して、なんらかのイベントが発生したらコールバックを実行してくれたほうがシンプルになるんじゃ?と思いついた。


ということで、CallbackEmit Eventsについて調べたので、両方の実装方法とどちらが良いのかをまとめる。

※ 以降、Callbackをコールバック方式、Emit Eventsをイベント方式と呼ぶ


親子コンポーネント間のデータの受け渡し(Pass Props/Emit Events)については、以下の記事を参照してほしい。


コールバック方式: コールバック関数を渡して実行する


<div id="cb">
   <my-button-callback :callback="notice"></my-button-callback>
</div>

<template id="my-button-callback">
  <div class="button">
    <button type="button" @click="callback('component')">Click(callback)</button>
  </div>
</template>
const MyButtonCallback = {
  template: '#my-button-callback',
  props: {
    callback: {
      type: Function,
      require: true
    }
  }
};

new Vue({
 el: '#cb',
  components: {
    MyButtonCallback
  },
  methods: {
    notice (val) {
      alert(`hello ${val} from callback`);
    }
  }
});

まずは親から子コンポーネントにコールバック関数を渡して、実行する方法。

こちらは単純で、親コンポーネントのnoticeメソッドをPropsに渡して、子コンポーネントでボタンがクリックされたときにコールバック関数を実行している。(@click="calback('component')"の部分)

今回はHTML内に書いたが、もちろん@clickで子コンポーネントのメソッドを呼び、そこからコールバック関数を実行することもできる。



イベント方式: 子コンポーネントからイベントを発火させる


<div id="emit">
  <my-button-emit @onclick="notice"></my-button-emit>
</div>

<template id="my-button-emit">
  <div class="button">
    <button type="button" @click="onClick('component')">Click(emit)</button>
  </div>
</template>
const MyButtonEmit = {
 template: '#my-button-emit',
  methods: {
    onClick (val) {
      this.$emit('onclick', val);
    }
  }
};

new Vue({
  el: '#emit',
  components: {
    MyButtonEmit
  },
  methods: {
    notice(val) {
      alert(`hello ${val} from emit`);
    }
  }
});

次にイベント方式。

子コンポーネントでクリックイベントが発生したら、onclickイベントを発火さるように定義してある。
あとは親コンポーネントはonclickイベントを待ち受けて、noticeメソッドを実行している(@onclick="notice"の部分)



Emit Events vs Callback


Vue.jsの公式フォーラムなどを検索したところ、以下のようなスレッドを見つけた。



Emit Events(this.$emit())もCallback(this.callback())もどちらも動作は同じだ。
基本的にEmit Events方式を優先させるが、あとは好みの問題な的なことが書かれていた。


双方試してみた感想として、次の理由からイベント方式が良いと感じた!

  1. コンポーネントをシンプルに保てる
  2. 依存関係がわかりやすい
  3. コールバック方式のthis.method()がメソッドなのかコールバックなのか一見わかりづらい


当記事で紹介したサンプルコードを見てもらうとわかると思うが、イベント方式のほうがシンプルで軽量な実装にできる
また、コールバック方式では子コンポーネントが親コンポーネントの実装に依存してしまう。それをイベント方式にすることで完全に分離できるのもポイントだ。


ということで私はイベント方式をオススメするが、公式ドキュメントにも「どちらを使うべき論」は書かれていないので、最終的には好きな方を選択するのが良いだろう。



以上

written by @bc_rikko

0 件のコメント :

コメントを投稿