Vue.jsには、コンポーネントを拡張する仕組みとしてミックスインという機能が用意されています。
ここでは、ミックスイン(mixin)について紹介します。
ミックスイン(mixin)
ミックスイン(mixin)とは、Vueのコンポーネントに再利用可能な機能を提供(コンポーネントオプションを再利用)する仕組みです。
多くのコンポーネントを実装していくと、同一の処理が複数のコンポーネントに必要な場合が発生します。
そのまま複数のコンポーネントに同一の処理を実装してしまうと、同一のコードが散在する状況が発生してしまいます。
そのような場合は、Vue.jsが用意しているミックスインを利用することで、同一のコード(共通のコード)を1か所に抜き出し、複数のコンポーネントに適用させることができるようになります。
ミックスインでまとめることができる処理
ミックスインでは、データ(dataプロパティオプションに定義するオブジェクト)、メソッド(methodsプロパティオプションに定義する関数)、ライフサイクルフック(createdやmountedなど)、算出プロパティ(computedプロパティオプションに定義する関数)などを共通化してまとめることができます。
ミックスインの定義
ここでは、ミックスインの基本を知るために簡単な例を示します。
1 2 3 |
<div id="app"> <my-comp></my-comp> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// ミックスインの定義 const myMixin = { mounted: function() { console.log(this.$data); } } // コンポーネントの定義 const myComp = { template: '<div>{{message}}</div>', data: function() { return { message: 'Hello Vue.js!' } }, mixins: [ myMixin ] } // Vueのインスタンスを生成 Vue.createApp({ components: { 'my-comp': myComp } }).mount('#app') |
ここでは、ミックスインにmountedフックを定義してコンソールにログを出力しています。
コンソールのログには、コンポーネント(my-comp)に定義したデータが出力されます。
1 2 3 4 |
Proxy {message: "Hello Vue.js!"} > [[Handler]]: Object > [[Target]]: Object > [[IsRevoked]]: false |
プロパティオプションのマージ
コンポーネントがミックスインを使用する際は、ミックスインに定義されているすべてのオプション(メソッドやライフサイクルフック)は、コンポーネントに定義されているプロパティオプションにミックスされます。
ミックスインとコンポーネントに同じオプションが定義されている場合は、それらのオプションがマージされます。
マージのルール
ミックスインとコンポーネントとで、同じオプションが定義されている場合は、以下のルールでマージされます。
- dataオプションは適切な方法でマージされます。同名のプロパティがある場合は、コンポーネント側の定義が優先されます。
- methods、computed、directivesでは、同じオブジェクトにマージされます。キー(名前)の重複がある場合は、コンポーネント側の定義が優先されます。
- ライフサイクルフックは、すべてのフックが実行対象となります。同名のフックがある場合は、ミックスイン → コンポーネントの順に実行されます。(ミックスインのフックが先に実行されます。)
- カスタムのオプションは、コンポーネント側の定義が優先されます。
グローバルミックスイン
特定のコンポーネントに定義する通常のミックスインに対して、すべてのコンポーネント(Vueアプリケーション)に対して適用するグローバルなミックスインを定義することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Vueのインスタンスを生成 const app = Vue.createApp({ myOption: 'Hello Vue.js!' }) // ミックスインの定義 app.mixin({ created() { const myOption = this.$options.myOption if (myOption) { console.log(myOption) } } }) // ルート要素のマウント app.mount('#app') |
上記のコードを実行すると、コンソールのログに
1 |
Hello Vue.js! |
が出力されます。
グローバルにミックスインを適用すると、アプリケーション内で作成されるすべてのVueコンポーネントインスタンスに影響します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Vueのインスタンスを生成 const app = Vue.createApp({ // アプリケーションにオプションを定義 myOption: 'Hello Vue.js from app!' }) // ミックスインの定義 app.mixin({ created() { const myOption = this.$options.myOption if (myOption) { console.log(myOption) } } }) // コンポーネントの定義 app.component('my-component', { // コンポーネントにオプションを定義 myOption: 'Hello Vue.js from component!' }) // ルート要素のマウント app.mount('#app') |
上記のコードを実行すると、コンソールのログには
1 2 |
Hello Vue.js! Hello Vue.js from component! |
が出力されます。