같은 기능이 여러 컴포넌트에서 공통으로 쓰이는 경우, 재사용하는 방법을 의미한다. 사용방법은 아래와 같이 크게 3단계로 나누어 사용할 수 있다.
1. 중복되는 코드를 js파일로 따로 분리하여 작성한다.
<!-- dataMixList.js -->
export default dataMixList = {
methods: {
ListFunc(date) {
if(date !== null) {
let hour = date.getHours();
return `${hour}`;
} else {
return null;
}
}
}
}
import { dataMixList } from './mixins/dataMixList.js'
mixins: [dataMixList]
vue3에서 상당히 유용하게 사용되는 것으로, 컴포넌트 내에서 사용하는 특정기능을 갖는 코드를 굉장히 유연하게 구성하여 사용할 수 있도록 vue3버전에 추가된 함수기반 API를 의미한다.
그동안의 vue의 단점이었던 프로젝트 규모가 커짐에따라 코드를 추적하기 어려운 점들을 극복하는데에 큰 도움이 된다는 장점이 있다. 이러한 이유로 vue3에서 부터는 Mixins보다는 Composition을 더 선호하는 것이 일반적이다.
실시간 변경사항에 대한 반응성을 적용시키는 기능을 한다.
reactive의 모든 프로퍼티의 반응성을 계속 유지하고 반환하는 기능을 한다.
<!-- compositionApi.vue -->
<template>
<div>
<h2>Calculator</h2>
<div>
<input type="text" v-model="num1" />
<span> + </span>
<input type="text" v-model="num2" />
<span> = </span>
<span>{{ result }}</span>
</div>
</div>
</template>
<script>
import {reactive, computed, toRefs} from "vue"; //toRefs 추가
function plusCalculator() {
let state = reactive({
num1: 0,
num2: 0,
result: computed(() => parseInt(state.num1) + parseInt(state.num2)),
});
return toRefs(state); //반응형으로 선언된 num1, num2, result를 외부 function에서 정상적으로 작동하도록 함
}
export default {
name:'calculator',
setup() {
let { num1, num2, result } = plusCalculator(); //외부 function
return {
num1,
num2,
result,
};
},
}
</script>
외부 파일로 일부 코드 추출하여 코드 가독성 향상
<!-- common.js -->
import {reactive, computed, toRefs} from "vue";
export function plusCalculator() {
let state = reactive({
num1: 0,
num2: 0,
result: computed(() => parseInt(state.num1) + parseInt(state.num2)),
});
return toRefs(state);
}
<!-- compositionApi.vue -->
...
import {plusCalculator} from '../common.js';
...
provide와 inject는 단어 그대로 각각 공급과 주입이라고 볼 수 있다. 이와 비슷한 예로 props를 들 수 있는데, props와 차이점으로는 props는 반드시 컴포넌트를 한 단계씩 거쳐야 하는 반면에 provide/inject는 중간단계없이 원하는 컴포넌트로 한번에 전달하기 때문에 비교적 단순한 계층구조를 가진다는 장점이 있다.
단점으로는, 중간단계가 없기 때문에 코드추적이 어렵다는 점을 들 수 있다.
<!-- CompositionProvide.vue -->
<template>
<CompositionInject />
</template>
<script>
import {provide} from 'vue';
import CompositionInject from "./CompositionInject.vue";
export default {
components:{CompositionInject},
setup() {
provide("title", "Vue.js 프로젝트");
}
}
</script>
<!-- CompositionInject.vue -->
<template>
<h1>{{title}}</h1>
</template>
<script>
import {inject} from 'vue';
export default {
setup() {
const title = inject('title');
return {title};
},
}
</script>