一般に、Vueで親コンポーネントから子コンポーネントへのプロパティ操作を行う場合、親コンポーネントの値を子コンポーネントにバインドします。
では子コンポーネントのメソッド操作を行う場合はどうするかというと、直接的には $refs
を通して子コンポーネントのメソッド呼び出しを行う方法があります。
// 子 const child = new Vue({ methods: { hoge: function () { console.log('hoge...'); } }, template: '<template>child.</template>' }) // 親 const parent = new Vue({ components: { child }, methods: { hoge: function () { this.$refs.child.hoge(); // 子コンポーネントメソッド呼び出し } }, template: '<template><child ref="child"/></template>' })
しかしながら、このような直接呼び出しは公式でも示されている通り非推奨です。
代わりに、Event Busを用いた子コンポーネント処理呼び出しの方法があります。
// EventBus const bus = new Vue(); // 子 const child = new Vue({ created: function () { bus.$on('hoge', this.hoge); // hogeイベントハンドラ登録 } methods: { hoge: function () { console.log('hoge...'); } }, template: '<template>child.</template>' }) // 親 const parent = new Vue({ components: { child }, methods: { hoge: function () { bus.$emit('hoge'); // hogeイベント発火 } }, template: '<template><child ref="child"/></template>' })
Event Bus自体は単純Vueコンポーネントオブジェクトです。
EventBusの $on
メソッドでイベントハンドラの登録を行います。第2引数にはイベント発火時に呼び出される関数を登録します。
イベントの発火はEventBusの $emit
を呼び出して行います。
子コンポーネントで予めイベントハンドラとして呼び出される関数を登録しておき、
親コンポーネントでは子コンポーネント関数を呼び出したいタイミングでイベントの発火を行います。
このようなイベント駆動によってメソッド呼び出しを行うことで、子コンポーネントの実装による親コンポーネントの実装の変更は発生しにくく、コンポーネント間の依存度を低く抑えることができます。 ただし、予め発生するイベントシグナルについては親子間で合意しておく必要があります。
小規模アプリのイベント伝播ではEventBusが役に立ちます。
ただし、中規模以上のアプリケーションを使用する場合はEventBusに登録するイベントが氾濫してしまうので、Vuex
を使用した状態管理/イベント伝播を使用すると良いと思います。