ビューファイルを調査している時に、EventBus
という表記に出会した。Vueの公式ファイルを調査していてもなかなか該当する項目がないので調べてみた。
EventBusとは?
コンポーネントが親子関係になくてもイベント情報の受け渡しができるようにすること。
EventBusの場合は、$emit
と$on
($off
)を使って受け渡しを行う。
(参考)子から親へのデータ受け渡し
$emit('イベント名', '渡すデータ')
を使って、親側で@イベント名='メソッド名'
で受け取る。
### EventBusを使ったデータの受け渡し 通常、`$emit`を使うときは`this.$emit`として、現在のビューインスタンスを指定するが、EventBusを使う場合は、イベントを渡す用の専用のビューインスタンスを用意する。(インスタンス名は任意)
//イベントバス専用のインスタンスを生成
const eventBus = new Vue();
//データ送信
eventBus.$emit('イベント名', 渡すデータ);
//受け取り
eventBus.$emit('イベント名', 実行するメソッド);
指定したイベント名をeventBusを介して送り、対象のメソッドを実行する。
実際はテンプレートをまたぐことになるため、生成したvueインスタンをプロパティで渡し、this.プロパティ名.$emit
やthis.プロパティ名.$on
で発火させる。
例として、vueインスタンスを格納した変数名をeventBusにしている。(指定はない)
実際の受け渡しの流れ
インスタンスの作り方はいろいろある。
mixins(定義したファイルの記述内容をそのまま読み込む)を使ってインスタンスの受け渡しをした場合。
import Vue from "vue"
export default {
data() {
return {
eventBus: new Vue(),
}
}
}
▼mixinsでインスタンスを読み込む
<template>
<button @click="onClick">送信</button>
</template>
<script>
import EventBus from "./EventBus"
export default {
name: "SendOrigin",
mixins: [EventBus],
data() {
return {
message: 'hello'
}
},
methods: {
onClick() {
this.eventBus.$emit('click-event', this.message)
}
}
}
</script>
**▼プロパティで受け取る** 親子関係でないテンプレートを用意する。どこかのテンプレートから、v-bindでvueインスタンスの情報を受け継いできた場合の例。(propsで受け取る)
・this.プロパティ名.$on('イベント名', 実行するメソッド名)
<script>
export default {
props: ['eventBus']
data () {
return {
msg: ''
}
},
mounted: {
//nullチェック
if(this.eventBus){
this.eventBus.$on('click-event', this.receiveMessage)
}
},
methods: {
receiveMessage (message) {
this.msg = "「${message}」を受信しました"
}
}
</script>
mounted以外でもwatchでイベントを受け取ることもある。
## eventBusの注意点 eventBusを使ったデータの受け渡しは、過去のVue公式ドキュメントに記載されていたが、今(2021/3時点)は記載されていない。
現在、公式ページではVuexの利用を推奨している。
![]() |
---|
($on
を使った受け渡しはbadと書いてある、、)
## (参考)子から親へのデータの受け渡し EventBusとの違いを見るため、通常の子から親へのデータ受け渡しを確認。
this.$emit
でイベント情報の受け渡しを行う。
thisは現在のビューインスタンス(親の中で呼び出しているので親)を表す。
実例
▼子テンプレートの設定
送信ボタンを押すと、onClick
メソッドが発火する。
$emitで親コンポーネントのclick-event
が発動する。親に送るデータは第2引数に記載。
・this.$emit('イベント名', 渡すデータ)
<template>
<button @click="onClick">送信</button>
</template>
<script>
export default {
name: 'ChiledVue',
data() {
return {
message: 'hello'
}
},
methods: {
onClick() {
this.$emit('click-event', this.message)
}
}
}
</script>
**▼親テンプレートの設定** `@イベント名`で$emitの発火情報を受け取り、指定したメソッドを実行する。
・@イベント名="メソッド名"
<template>
<ChiledVue @click-event="receiveMessage">{{msg}}</ChiledVue>
</template>
<script>
import ChildVue from './ChildVue'
export default {
components: {
ChildVue
},
data () {
return {
msg: ''
}
},
methods: {
receiveMessage (message) {
this.msg = "「${message}」を受信しました"
}
}
}
</script>
通常、$emit経由で受け取ったデータをメソッドの中で処理して、その結果をビューの中で使う。