1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue2.0で$broadcastと$dispatchの再現方法を紹介します

Last updated at Posted at 2019-11-21

Vue1.0では、$broadcast$dispatchが実装されています、例え多層数としても、指定されるコンポーネントにbroadcastまたはdispatchで通信することができます。

下記の通りです:

<componentA @dispatchFromComponentC="alert($event)">
  <componentB>
    <componentC @broadcastFromComponentA="alert($event)">
    <componentC/>
  <componentB/>
<componentA/>
componentA.vue
// componentA
$vm.broadcast("broadcastFromComponentA", "i am componentA")
componentC.vue
// componentC
$vm.dispatch("dispatchFromComponentC", "i am componentC")

コンポーネントAは子コンポーネントBにイベントをbroadcastし、子コンポーネントBがイベントをリッスンし、trueを返すと、引き続き孫コンポーネントCにイベントをbroadcastします。

逆に、コンポーネントCは親コンポーネントBにdispatchし、親コンポーネントBがイベントをリッスンし、trueを返すと、引き続き祖父コンポーネントAにイベントをdispatchします。

しかし、これら二つのメソッドはもうVue 2.0で削除されました。this.$parent.$parent.$parentthis.$children.$children.$childrenなどの書き方を避けるために、今回は、Elementのbroadcastとdispatch再現方法をご紹介させていただきます。

ソースコードはこちらです

function broadcast(componentName, eventName, params) {
  /*broadcastを発行するコンポーネントの下の全ての子コンポーネントをトラバースします*/
  this.$children.forEach(child => {
    /*子コンポーネント名を取得*/
    var name = child.$options.componentName;
    if (name === componentName) {
      /*当コンポーネントは指定されているコンポーネントの場合、$emitでイベントを送出する。
      (注意:指定されているコンポーネントでイベントを受け取るために、
   事前に$onリスナを追加するのは必要です。)*/
      child.$emit.apply(child, [eventName].concat(params));
    } else {
      /*当コンポーネントは指定されているコンポーネントではない場合、
      broadcast関数で再帰して、当コンポーネントの下の全ての子コンポーネントをトラバースします。*/
      broadcast.apply(child, [componentName, eventName].concat([params]));
    }
  });
}
export default {
  methods: {
    dispatch(componentName, eventName, params) {
      var parent = this.$parent || this.$root;
      /*親コンポーネント名を取得*/
      var name = parent.$options.componentName;
      while (parent && (!name || name !== componentName)) {
        /*当コンポーネントは指定されているコンポーネントではない場合、上層へ探し続きます*/
        parent = parent.$parent;
        if (parent) {
          name = parent.$options.componentName;
        }
      }
      /*当コンポーネントは指定されているコンポーネントの場合、$emitでイベントを送出する。
      (注意:指定されているコンポーネントでイベントを受け取るために、
   事前に$onリスナを追加するのは必要です。)*/
      if (parent) {
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    },
    /*ここで、call関数で上記定義したbroadcast内部のthisを当Vueインスタンスに変更する*/
    broadcast(componentName, eventName, params) {
      broadcast.call(this, componentName, eventName, params);
    }
  }
};

以上です、役に立ってば幸いと思います:grin:

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?