Mixinとは
公式から
ミックスイン (mixin) は、Vue コンポーネントに再利用可能で柔軟性のある機能を持たせるための方法です。ミックスインオブジェクトは任意のコンポーネントオプションを含むことができます。コンポーネントがミックスインを使用するとき、ミックスインの全てのオプションはコンポーネント自身のオプションに”混ぜられ”ます。
つまり、Mixinに書かれているものが読み込んだ先で利用できる(再利用できる)
mixins/mixin.js
export const myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
// eslint-disable-next-line no-console
console.log('hello from mixin!')
}
}
}
create時に「hello from mixin!」がconsoleに出力される
App.vue
<template>
<div></div>
</template>
<script>
import { myMixin } from "./mixins/mixin";
export default {
mixins: [myMixin]
};
</script>
オプションのマージ
データのマージ
mixins/mixin.js
export const myMixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
dataがマージされ、「foo追加」「messageはgoodbyeで上書き」となる
App.vue
<template>
<div></div>
</template>
<script>
import { myMixin } from "./mixins/mixin";
export default {
mixins: [myMixin],
data: function() {
return {
message: "goodbye",
bar: "def"
};
},
created: function() {
// eslint-disable-next-line no-console
console.log(this.$data);
// => { message: "goodbye", foo: "abc", bar: "def" }
}
};
</script>
フック関数のマージ
mixins/mixin.js
export const myMixin = {
created: function () {
// eslint-disable-next-line no-console
console.log('mixin hook called')
}
}
mixin「created」⇒component「created」の順に実行される
App.vue
<template>
<div></div>
</template>
<script>
import { myMixin } from "./mixins/mixin";
export default {
mixins: [myMixin],
created: function () {
// eslint-disable-next-line no-console
console.log('component hook called')
}
};
</script>
// => "mixin hook called"
// => "component hook called"
methodsのマージ
オブジェクトの値を期待するオプションは、例えば、methods、components、そして directives らは同じオブジェクトにマージされます。コンポーネントオプションはこれらのオブジェクトでキーのコンフリクトがあるとき、優先されます:
mixins/mixin.js
export const myMixin = {
methods: {
foo: function () {
// eslint-disable-next-line no-console
console.log('foo')
},
conflicting: function () {
// eslint-disable-next-line no-console
console.log('from mixin')
}
}
}
App.vue
<template>
<div></div>
</template>
<script>
import { myMixin } from "./mixins/mixin";
export default {
mixins: [myMixin],
methods: {
bar: function() {
// eslint-disable-next-line no-console
console.log("bar");
},
conflicting: function() {
// eslint-disable-next-line no-console
console.log("from self");
}
}
};
</script>
methodsがマージされ、「conflicting()」はコンポーネント側が優先される
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
MixinのMixin
mixins/mixin.js
export const myMixin = {
data: function () {
return {
foo: 'abc'
}
}
}
mixins/mixin2.js
export const myMixin2 = {
data: function () {
return {
bar: 'def'
}
}
}
mixins/marge-mixin.js
import { myMixin } from "./mixin";
import { myMixin2 } from "./mixin2";
export const myMixinx = {
mixins: [myMixin,myMixin2]
}
App.vue
<template>
<div></div>
</template>
<script>
import { myMixinx } from "./mixins/marge-mixin";
export default {
mixins: [myMixinx],
created: function() {
// eslint-disable-next-line no-console
console.log(this.$data);
// => { foo: "abc", bar: "def" }
}
};
</script>
Mixinの利用方針
- グローバルは極力使わない
- 名前の競合は基本しない
- そのコンポーネントに極力必要な分だけimportする(コンポーネントで使用しないdataやmethodを減らす)
- コンポーネントのthisを参照するような密結合な設計はしない
- Mixinがコンポーネントからの暗黙的な利用にならないよう、ファイル名(import名)、メソッド名から推測できるものにする