背景
今までVue.jsのコンポーネント間のイベント通信を行わせる時に、$dispatch()
と$broadcast()
を用いたことが多いです(Vue.js及びコンポーネントについては公式ページをご参考ください)。しかし、これらはVue.js 2.0で廃止される予定です^1。コンポーネントのツリー構造の膨大化によって追跡が難しくなることと兄弟コンポーネントの通信がやりにくいことが理由として挙げられています。その代わりに、Node.jsのEventEmitterパターンが推奨されています^2。このやり方はVue.js 1.0のAPIを使って実現できます^3ので、まだ2.0に移行していなくても、これからイベント通信を書く時に使用すべきでしょう。
移行の手順
下記のコードを2.0の書き方に移行するとしましょう。
1 | <div id="app"> |
1 | var CompA = Vue.extend({ |
1. まず、新しいVueインスタンスを作成し、イベントハブの役割を担わせます。
1 | var bus = new Vue(); |
2. 送信側は$dispatch
か$broadcast
を使用してイベントを発信していましたが、イベントハブに一旦送信するので、全てを$emit
に書き換えます。
1 | // old |
3. 受信側において、今まではリッスンしたいイベントをeventsで定義していましたが、その内容をcreatedでイベントハブの$on
に結びつけ、リッスンしてもらいます。
1 | // old |
4. 最終的なコードはこんな感じになります。
1 | var bus = new Vue(); |
まとめ
移行のイメージは下記の図のようにまとめられると思います。
ComponentsEventCommunication.png
全てのイベントを一旦Busというハブに送り、そしてハブからリッスンしているところにイベントを送信します。イメージ図だけを観察したら、やや複雑になってきましたが、前に挙げた2つの欠点が確かに解消できました。
しかし、全てのイベントがまとめられて同じところに送信する必要があるため、間違って意図しなかったコンポーネントに送ってしまう可能性も高くなってきていますので、気をつける必要があります。また、この設計にしたら、Vuexとほぼ変わらない感覚になってしまいます^4ので、Vuexを面倒くさがらず、いっそ導入してしまえばとも思いますね。
Vuexを使って実装してみよう
Vuexを使用して実装するのに、Vuexのstoreを追加してインスタンスに入れ、stateとmutationを配置し、getterとactionを作成する必要があります。また、今回においてコンポーネントに表示すべきなテキストは最初から決められているわけでないため、computeを使ってtextを計算した方が妥当でしょう。Vuexを使った実装は下記のようになります。
1 | // -- Vuex -- |
基本的な考え方は送信がactionで行い、受信がgetterでやることです。
真・まとめ
Vue.jsの発達によって、Vueで大規模なサービスを構築するケースも増えてきていますので、従来のdispatch/broadcastの考え方が追いつけなくなりました。dispatch/broadcastのようなやり方より、ハブのようなものを利用し、データの保存・転送を行うことが望ましくなってきました。なので、Vue.js 2.0においてdispatchとbroadcastを廃止してしまってもおかしくありません。今からVue.jsでサービスを作り始めたい場合、早々からVuexを導入してもいいかもしれませんね。