propsに関数を渡すのは Vue.js のアンチパターンである
Reactでは、親コンポーネントから子コンポーネントへ、関数をプロップとして渡すことができます。
関数の呼び出しは、子から親へと逆流し、親子のコンポーネントのコミュニケーションを促進します。
これは、Vue.jsでも次のようなコードで実現できます。
<template> <Child :callback="doSomething" /> </template> <script> export default { name: 'Parent', methods: { doSomething() { // } } } </script>
そして、子コンポーネントでは、関数をpropとして受け取ります。
<template> <a @click="execute">Execute action</a> </template> <script> export default { props: { callback: { type: Function } }, methods: { execute() { // ... do something here if (this.callback) { this.callback() } } } } </script>
Vue.js ではカスタムイベントを使う
上の例は完璧に動作しますが、Vueではほとんどの場合、アンチパターンとみなされます。
関数をpropとして渡すことで、親と子の両方のコンポーネントを双方向のデータバインディングでリンクしています。
上の例では、子コンポーネントは親コンポーネントの関数propのコンテキストを知る必要があります。実行するたびに、渡されたコールバック関数をチェックして実行する必要があります。
この子コンポーネントを再利用すると、異なる親から渡された異なるコールバック関数を持つようになります。
アプリケーションのサイズが大きくなり、他の開発者が参加するようになると、子コンポーネントのコードを見て、どのコールバック関数のプロップなのか、それがどこから来たのかを理解しなければなりません。
その代わり、Vue.jsには、同じことを実現するカスタムイベントシステムがあります。
# Parent <template> <Cat @onHappy="doSomething" /> </template> <script> export default { name: 'Parent', methods: { doSomething() { // } } } </script> # Child Cat component <script> export default { methods: { eats() { this.$emit('onHappy') } } } </script>
Catコンポーネントのeatsメソッドが呼び出されるたびに、onHappyイベントが発行されます。
親はonHappyイベントを待ち、対応する関数を呼び出すことができます。データの流れは一方向だけなので、デバッグも非常に楽になります。
関数を prop として渡すことの利点は、コードがよりクリーンでDRYになることです。
イベントを発生させてそれを待つのではなく、関数を渡してそれを子コンポーネントから呼び出すことができます。
ほとんどの場合、これは良いアイデアではありませんが、2つのコンポーネントがどのような場合でも結合されなければならず、子コンポーネントが他のシナリオで再利用されない場合は、この方法を検討すると良いでしょう。
とはいえ、ほとんどの場合、イベントはメインのアプローチであるべきで、これは最大限の注意を払って使用するべきです。