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.$parent
やthis.$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);
}
}
};
以上です、役に立ってば幸いと思います。