컴포넌트 전체를 재사용하는 기법이 HOC.
부분적인 로직을 재사용하는 기법은 바로 이번 포스팅 주제인 Mixin이다.
믹스인(Mixins)은 Vue 컴포넌트에 재사용 가능한 기능을 배포한다.
믹스인 객체는 모든 컴포넌트의 옵션을 포함할 수 있고, 컴포넌트가 믹스인을 사용하면, 믹스인의 모든 옵션이 컴포넌트의 자체 옵션으로 "혼합"된다.
즉, mixin에 data를 지정하고 컴포넌트에서 사용할 때 별도 data를 지정하지 않아도 mixin에 정의되어 있는 data로 지정된다.
아래 코드를 보자.
// mixin.js
export const mixin = {
data() {
return {
num: 1
}
}
}
//Test.vue
import { mixin } from './mixin.js';
<script>
export default {
mixins: [mixin]
}
</script>
<!-- <script>
export default {
data() {
return {
num: 1
}
}
}
</script>-->
옵션 병합
믹스인과 컴포넌트 자신은 중복되는 옵션을 가지고 있는 경우에는 적절한 방법을 사용해서 "병합"된다.
const myMixin = {
data() {
return {
message: 'hello',
foo: 'abc'
}
}
}
const app = Vue.createApp({
mixins: [myMixin],
data() {
return {
message: 'goodbye',
bar: 'def'
}
},
created() {
console.log(this.$data) // => { message: "goodbye", foo: "abc", bar: "def" }
}
})
data 객체가 충돌하는 경우에는 컴포넌트의 data 객체가 우선순위를 갖으면서 병합된다.
const myMixin = {
methods: {
foo() {
console.log('foo')
},
conflicting() {
console.log('from mixin')
}
}
}
const app = Vue.createApp({
mixins: [myMixin],
methods: {
bar() {
console.log('bar')
},
conflicting() {
console.log('from self')
}
}
})
const vm = app.mount('#mixins-basic')
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
methods, components, directives같은 객체 값을 요구하는 옵션은 같은 객체에 병합된다.
이러한 객체에 충돌하는 키가 있을 경우, 컴포넌트의 옵션이 우선순위를 갖는다.
mixin을 이용하여 중복되는 로직을 줄여보자.
// mixin/ListMixin.js
import bus from '../utils/bus.js';
export default {
created() {
bus.$emit('start:spinner');
this.$store.dispatch('FETCH_LIST', this.$route.name)
.then(() => {
bus.$emit('end:spinner');
})
.catch(err => {
console.log(err);
});
},
}
//NewsView.vue
<template>
<div>
<list-item />
</div>
</template>
<script>
import ListItem from '../components/ListItem.vue';
import ListMixin from '../mixins/ListMixin.js';
export default {
components: {
ListItem
},
mixins: [ListMixin]
};
</script>