Mixins은 여러 컴포넌트 간에 공통으로 사용하고 있는 로직, 기능들을 재사용하는 방법이다. Mixins는 컴포넌트의 옵션과 동일한 옵션들을 모두 정의할 수 있다. 컴포넌트가 Mixins를 사용하면, Mixins의 모든 옵션이 컴포넌트 자체 옵션으로 혼합된다. 중복된 옵션이 있는 경우, 적절한 방법을 사용해서 병합된다.
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"}
}
});
const myMixin = {
created() {
console.log('mixin hook called');
}
};
const app = Vue.createApp({
mixins: [myMixin],
created() {
console.log('component hook called');
}
});
// => "mixin hook called"
// => "component hook called"
const myMixin = {
methods: {
foo() {
console.log('foo');
},
conflicting() {
console.log('from mixin');
}
}
};
const app = Vue.createApp({
mixins: [myMixin],
methods: {
bar() {
console.log('bar');
},
comflicting() {
console.log('from self');
}
}
});
const vm = app.mount('#mixins-basic')
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
다이얼로그(모달 혹은 팝업 창)의 열기, 닫기 로직을 Mixins에 정의했다.
var DialogMixin = {
data() {
return {
dialog: false;
};
},
methods: {
showDialog: {
this.dialog = true;
},
closeDialog: {
this.dialog = false;
}
}
};
컴포넌트에 DialogMixin이 주입되었기 때문에 closeDialog 메서드가 LoginForm 컴포넌트에 없더라도 주입된 closeDialog 메서드를 사용할 수 있다.
import { DialogMixin } from './mixins.js';
export default {
// ...
mixins: [DialogMixin],
methods: {
submitForm() {
axios.post('login', {
id: this.id,
pw: this.pw
}).then(() => this.closeDialog())
.catch((error) => new Error(error));
}
}
}
Vue 2에서는 Mixins은 컴포넌트 로직을 재사용할 수 있게 만드는 주 도구였지만, 병합으로 인한 잦은 충돌 및 속성 파악에 여러움이 있었고, 논리 변경을 위해 매개 변수를 Mixins에 전달할 수 없었기 때문에 논리를 추상화할 때 유연성이 떨어져 재사용성이 제한되었다. 이런 문제 해결을 위해 Vue 3에서는 Composition API를 추가했다.
Composition API는 옵션을 선언하는 것 대신 가져온 함수를 사용하여 Vue 컴포넌트를 작성할 수 있는 API이다. 기존에 사용하던 Option API를 사용해서 논리 구조를 분리하고 재사용 가능하도록 하는 것을 목적으로 만들어졌다.
Vue 2까지 사용하던 Mixins를 활용하여 코드를 재사용할 수 있었으나 병합으로 인해 발생하는 여러 가지 문제로 인해 Vue 3 추가되었다. Composition API는 Vue 3 내장 기능이지만 현재 공식적으로 유지 관리되는 @vue/composition-api 플러그인을 통해 Vue 2에서도 사용할 수 있다.
Composition API는 다음 API를 포괄하는 상위 용어이다.
setup 컴포넌트 옵션은 Composition API의 진입점 역할을 한다. 컴포넌트가 생성되기 전에, props가 한번 resolved될 때 실행된다.
setup이 실행될 때, 컴포넌트 인스턴스가 아직 생성되지 않아 setup 옵션 내에 this가 존재하지 않는다. 즉, props를 제외하고 컴포넌트 내 다른 속성에 접근할 수 없다.
<script>
import { ref, onMounted } from 'vue';
export default {
setup() {
const count = ref(0);
function increment() {
count.value ++;
}
onMounted(() => {
console.log(`The initial count is ${count.value}.`);
}
return {
count,
increment
}
}
});
</script>
<template>
<button @click="increment">Count is : {{ count }}</button>
</template>
Vue 3에서 Composition API는 주로 Single-File Components의 <script setup>
구문과 함께 사용된다.
<script setup>
import { ref, onMounted } from 'vue';
const count = ref(0);
function increment() {
count.value ++;
}
onMounted(() => {
console.log(`The initial count is ${count.value}.`);
});
</script>
<template>
<button @click="increment">Count is : {{ count }}</button>
</template>
import { ref } from 'vue';
export default DialogUtil = () => {
const dialog = ref(false);
const showDialog = () => {
dialog.value = true;
};
const closeDialog = () => {
dialog.value = false;
};
return { dialog, showDialog, closeDialog };
};
import { DialogUtil } from './utils.js';
export default {
setup() {
const { closeDialog } = DialogUtil();
const submitForm = () => {
axios.post('login', {
id: this.id,
pw: this.pw
}).then(() => closeDialog())
.catch((error) => new Error(error));
};
return {
submitForm
};
}
}