子孫コンポーネントへの通信のベストプラクティスってなんでしょう?



  • Vue2.0では$dispatchと$broadcastが、アンチパターンとして廃止されるそうですが、
    $broadcastに代わってどのように子孫に通信するといいのでしょうか?

    たとえば、以下のような親子関係のあるフォームなどで。
    https://jsfiddle.net/62L31zc7/

    vuexやemitterを使えばいいらしいと聞きますが、
    実際どう使っていけばいいのよくわからないので、教えていただけたらありがたいです。



  • その場合でしたら単純に this.$broadcast をすべての子要素に対する $emit に変えれば良いような気がするのですが、いかがでしょうか?
    https://jsfiddle.net/ktsn/uwwo72bt/4/

    あとは、このケースだとちょっと難しいかもしれないですが、イベント仲介用の Vue インスタンス (イベントバス) を作るのも良いかと思います。
    イベントバスを介すことで、イベントの伝播が DOM の構造に依存しなくなり、また、イベントがどこに向けられているのかが明確になるので、コードがわかりやすくなるメリットがあります。(https://github.com/vuejs/vue/issues/2873How to Deal with Deprecation of $dispatch and $broadcast? に書いてある内容です)

    Vuex を使うときは、元となるデータの保持や、データの操作はコンポーネント内ではなく、Vuex の Store の中に置くことになります。
    ちょっとデータ構造も工夫することになりますが、Vuex っぽく書くととこんな感じになります (Vuex の Store の代わりに Vue のインスタンスを store として使ってます)。
    データの操作はすべて store の中で行われ、コンポーネントは変更されたデータを表示するだけになっています。
    https://jsfiddle.net/ktsn/55d7f5dg/2/

    Vuex はこの例の store をもっと強力にしたものだと考えてもらえれば良いかと思います。



  • なるほど、画面と結びつけないVueインスタンスという利用法もあるんですね。

    たしかにイベント機能だけ取り出して直接コンポーネントを指定すれば明瞭ですし、
    再帰するコンポーネントは再帰するデータから生み出されたのだから、
    $dispatchでコンポーネントツリーを走らせるより、元のデータを走査するのが道理です。

    色々と目から鱗が落ちました。ありがとうございます。


Log in to reply