概要
vue-router使用時の「子→親」あるいは「子1→子2」のイベント渡しの記述方法について自分用メモ
ソースコードは簡略化したもので、ちゃんとテストしていないので動かないかも
サンプルコード
this.$router.app.$on
を扱うのがポイント。
それ以外は通常のイベントバスのやり方と同じ。
主要な部分 ( app.js )
//(前略)
const app = new Vue({
router, // これが「ルーターインスタンスを root インスタンスに router オプションとして」かな?
el: '#app',
render: h => h(App)
});
親コンポーネント ( parent.js )
<template>
<div>
<child1></child1>
<child2></child2>
</div>
</template>
<script>
// 子2つを配置するのみ
import component_child1 from './child1.vue'
import component_child2 from './child2.vue'
export default {
components: {
'child1': component_child1,
'child2': component_child2
}
};
</script>
子コンポーネント(child1.vue, child2.vueの2つ)
目標とする動作は下記。
- child1でボタンを押すと
test_method_child1
が実行される。 test_method_child1
内でtest_event_global
がスローされ、child1は非表示。- child2でイベントの解除(重要、後述。参考資料を参照。)
- child2ではイベントを
test_event_global
をtest_event_child2
としておく。 - child2でイベントを受け取ったら、
v-on:test_event_child2
でtest_method_child2
が実行。 - child2が表示され、Hello Worldが見える。
<template> <div v-show="visible_child1"> <button v-on:click="test_method_child1">Run Test</button> </div></template><script>export default {
data() {
return {
visible_child1 : true // 表示/非表示制御
};
},
methods: {
test_method_child1() {
this.visible_child1 = false;
// イベントバスを this.$router.app として、イベントをスロー
this.$router.app.$emit('test_event_global');
}
}
}
</script>
<template> <div v-on:test_event_child2="test_method_child2" v-show="visible_child2"> Hello world !!
</div></template><script>export default {
data() {
return {
visible_child2 : false // 表示/非表示制御
};
},
mounted() {
// イベントバスを this.$router.app として、コンポーネントのイベントに紐づけている
this.$router.app.$off('test_event_global');
this.$router.app.$on('test_event_global', this.test_event_child2);
},
methods: {
test_method_child2() {
this.visible_child2 = true;
}
}
}
</script>
注意点
- 下記、参考資料2 Vue.js のグローバルイベントバスでの親子間以外の通信と vue-router より引用
解除が行われない、というより .$off をしないと蓄積するようです
ページ遷移して created や mounted が何度も呼ばれると、そのたびに蓄積されてしまうらしい。
( beforeDestroy か destroyed の中で解除すればいいのかな )
上記は例。$onでメソッドを直接叩くこともできるはず。
表示/非表示みたいなことを実現するだけならv-onは取ってしまって、child2.vue で、
<div v-show="visible_child2">
(中略)
this.$router.app.$on('test_event_global', this.test_method_child2);
とすることも。