質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.26%

  • Vue.js

    233questions

Vue イベントの使い途

受付中

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 96

mochi.monaka

score 5

ここでの「イベント」とは、コンポーネント親子間での通信でなく、
$on でのリッスンや、いわゆるイベントバスとしての Vue インスタンスを別途設けて利用する手法を指します。

それらの仕組みや使い方については一応理解しているつもりで、
お訊きしたいのは「使い方」でなく「使い途」です。

Vue 1.x の頃は、 $dispatch $broadcast のような考え方があり、
つまりイベント発行先を特定せずに「自分のすべての祖先コンポーネント」「自分のすべての子孫コンポーネント」にイベントを一斉に「降らせる」ことができました。
これはこれで使いどころがあったと思います。

しかし Vue 2.x 現在では、
たとえば $root や $refs.xxx 等で送信先を特定して、それに向けて $emit すると思うのですが、
特定できるならイベントでなく特定先のメソッドを単に直接呼び出せばよいだけではないか、「イベント」の使い途、使いどころ、メリットは何か、いまいちピンと来ません。

発行先を特定する前提なので「イベントならツリーに依存せずに…」のような言い方は当てはまらないと思います。

メソッド呼び出しなら、引数設計も自由、戻値を期待することもでき、非同期な処理内容であっても Promise を返却してもらったり自由ですが、イベントは投げっぱなしで、使い途やメリットが思いつきません。

どちらかといえばグローバルな使途を想像しています。
グローバルとはたとえば、ECサイトでいえば、「カートに入れる」処理を商品詳細ページで呼び出せるだけでなく、トップ画面のメインバナーに表示される商品や、どのページでも表示されるサイドバーにあるオススメ商品もカートに入れることができる仕様のとき、どこからでも「カートに入れる」処理を持つ唯一の先に指示を出せる、という意味です。
イベント発行にあたりその唯一の先を「特定」できる時点で、イベントを介さずにメソッドを直接呼び出せばよいのでは、と思うのです。

あるいは、イベント送信先の「特定」は不要なのでしょうか?

「イベント」がハマる使いどころや、もしくは私がそもそもイベントの仕組みを誤解しているなど、ご意見やご指摘を頂けますでしょうか。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

そもそもですが

$root や $refs.xxx 等で送信先を特定して

これはどこの情報によるものでしょう?

公式ドキュメントでは,

空の Vue インスタンスを中心のイベントバス

となっており,送信先を特定しているわけではないと思います.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/15 04:22

    ご回答ありがとうございます。

    >>`$root` や `$refs.xxx` 等で送信先を特定して
    >これはどこの情報によるものでしょう?

    どこかに記載があるわけでなく、私が考える「特定」の一例です。

    あるコンポーネントにイベントを直接発行したいのだったら `this.$refs.xxx.$emit('...')`

    イベントバスを使うのだったら `this.$root.EventBus.$emit('...')`
    EventBus の場所自体から特定を要してしまうので、たとえば `$root` に生やしておく、という特定の一例です。

    「イベント発行先を特定する」こと自体に違和感はあるのですが、いまの私の理解では、とはいえ発行先を特定しないことには発行しようがなく。。
    ここで根本的に誤解しているような気もしています。。

    ---

    引用なさった [公式ドキュメント](https://jp.vuejs.org/v2/guide/components.html#%E8%A6%AA%E5%AD%90%E9%96%93%E4%BB%A5%E5%A4%96%E3%81%AE%E9%80%9A%E4%BF%A1) のコードは、仕組みを示すだけの概念的なものと思います。

    一箇所で `var bus = new Vue()` として生成した `bus` 、これを「コンポーネント A」でも「コンポーネント B」でも使っています。
    イベントバスの概念は示されていますが、どうやって `bus` を共用しているのかは示されていません。
    私は、そこがわからないので、概念や理屈はわかっても利用場面が想像できないのかもしれません。

    イベントバスの概要説明をするだけの以下のようなミニマムなコード、
    つまりワンソースの中で同じ `bus` をどちらのコンポーネントからも使うならよいのですが、
    [http://jsfiddle.net/ph40zm8b/](http://jsfiddle.net/ph40zm8b/)
    ```html
    <div id="app">
    <component-a></component-a>
    <component-b></component-b>
    </div>
    ```

    ```js
    const bus = new Vue() // 唯一のバス

    Vue.component('component-a', {
    template: '<p>component-a</p>',
    created() {
    // 唯一のバスを利用
    bus.$on('event1', () => console.log('event1'))
    },
    })

    Vue.component('component-b', {
    template: '<button @click="onClick">component-b</button>',
    methods: {
    onClick() {
    // 唯一のバスを利用
    bus.$emit('event1')
    }
    },
    })

    new Vue({
    el: '#app',
    })
    ```
    しかし現実的には各コンポーネントはそれぞれ別のソースに書かれます。

    各コンポーネントでそれぞれイベントバスを新規生成していては無意味で、生成済の唯一のイベントバスを各コンポーネントで共用する必要があると思います。
    「特定」とはvmの特定に限らず、バスならバスの特定も必要と思います。

    そこで私は、どのコンポーネントからでも同じ `bus` インスタンスにアクセスできるように(場所を特定できるように)、(たとえば) `$root` に生やすと考えます。

    そう考えた時点で、ではイベントでなく `this.$root.bus.method(...)` と直接呼び出せばよいのではとか、 `bus` 自身はメソッドを実装せず単なる経由なら `bus` もまた最終的なメソッド実装先を「特定」しなければならず、特定できるなら最初からイベントでなく直接呼び出せば、、と思ってしまうのです。

    ---

    この質問はおそらく「どうやって唯一のイベントバスを共用する(使い回す、持ち回る)のか」が正しい標題になる気がしてきました。。

    - まず、生成済の唯一のイベントバスを各コンポーネントで共用する「必要がある」のは正しいでしょうか?
    - その共用は、どういうやり方が考えられるでしょうか? 生成済インスタンスの `export` `import` の仕方があるとか、結局グローバル変数に持つとか。


    話がVuexに広がる可能性がありますが、あくまで「イベント」の範囲で理解したいと思います。

    キャンセル

  • 2017/12/15 07:18

    > イベントでなく `this.$root.bus.method(...)` と直接呼び出せばよいのではとか
    「bus内に限定した形で,Vue 1.x の頃のような `$dispatch` `$broadcast`が使える」と考えてはいかがですか?

    キャンセル

  • 2017/12/18 08:46

    ありがとうございます。
    前回書きました、その「busを各コンポーネントでどう共有するのか」については、一般的にどういうやり方が多そうでしょうか?
    まずそこがはっきりすると、考えかたの方向の見当がついてくる気がします。


    なにかできないことを解決したいみたいな行きたい方向の決まっている質問でなく、イベントはどんなシーンでどんな使い方をするのがハマるんだろうとか考え方の話なので、いまはどっち向くのが正しいわけでもなく。。
    そもそもの質問の趣旨が、$onや$emitの使い方とか動かないとかでなく、みなさんどう使われているのかいろんな意見を聞いてみたい、というようなものですので。

    数日の間に、イベントを使って動作するサンプルを幾つか書いてみましたが、まだやはり、なにが嬉しいのかわかりませんでした。。

    キャンセル

  • 2017/12/18 10:14

    どのようなやり方が一般的かに関わらず,「Vue 1.xと同様の使い方が出来る」と考えれば納得しやすいと思いますが(Vue 1.xについては納得して頂いてるわけですから).
    ここはQ&Aサイトなので,いろんな意見を聞くならVue.jsのSlackやフォーラムのほうが良いかもしれません.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.26%

関連した質問

同じタグがついた質問を見る

  • Vue.js

    233questions