composition api(Vue2 기준)
- vue2에서는 따로 설치 해야 하며 vue3에서는 기본으로 내장 되어있다.
- 컴포넌트를나 코드를 재사용 하기 위해서 기존에 mixin이나 Higher-Order Components 사용하여 재상 하였다 캡틴 판교님에 의하면 mixin,Higher-Order Components 지양하고 composition api 사용해야 된다. vue의 방향이 composition api 이다.
설치 방법
npm install @vue/composition-api
main.js 기본 설정
- main.j에 import 후 Vue.use(VueCompositionAPI); 후 사용해야 함.
import VueCompositionAPI from '@vue/composition-api';
Vue.use(VueCompositionAPI);
setup()
- data()에서 사용하는 방식이 setup() 함수로 변경 된다.
- setup() 내에서 ref(), reactive() 통해 초기 값을 설정이 가능 하다
- reactive()는 선언 후 새로운 객체를 넣거나 하면 변경 된 값이 template의 태그에 있는 값이 랜더링 되지 않는다. ref를 사용하자 (경험)
- ref() 선언된 값을 script 내에서 사용하려면 value를 사용해야 한다.
User.value.name, test1.value , test2.value
- ref를 통해 선언 한 값은
let test1 = ref(0);
return 에 포함시켜 template에서 사용한다.
- 함수는 기존에 methods:{} 선언하여 사용하였는데 사용하지 않고 setup() 안에 선언 후 마지막이 return에 포함 시켜주면 된다.
- computed는 computed:{} 사용하는 방식이 없어지고 만들 함수를 computed() 함수로 넘겨 준후 사용 하면 된다. 소스 참조
- router나 store는 기존에 this.store,this.router 사용하지 않고 getCurrentInstance() 통해 받은 object를 통 접근이 가능 하다 아래 소스 참조
- 생명 주기 setup() 안에 생명주기에 해당하는 함수를 선언하면 생명주기에 따른 함수가 호출 된다. 기존에 사용하던 방식에서 이름들이 변경 되었다.
- beforeCreate -> setup()
- created -> setup()
- beforeMount -> onBeforeMount
- mounted -> onMounted
- beforeUpdate -> onBeforeUpdate
- updated -> onUpdated
- beforeDestroy -> onBeforeUnmount
- destroyed -> onUnmounted
- activated -> onActivated
- deactivated -> onDeactivated
- errorCaptured -> onErrorCaptured
<template>
<div>
<div>{{ User.name }}</div>
<div>{{ test1 }}</div>
<div>{{ test2 }}</div>
<div>{{ getLabel }}</div>
<div>{{ id }}</div>
<button @click="buttonClick()">이름 변경</button>
<button @click="back()">뒤로가기</button>
</div>
</template>
<script>
import { ref, computed, getCurrentInstance, onMounted} from '@vue/composition-api';
export default {
setup(props,context) {
let test1 = ref(0);
let test2 = ref([1, 2, 3]);
let User = ref({ name: '1111111', age: 29 });
let buttonClick = () => {
User.value.name = 'dddddddddddddd';
};
const getLabel = computed(() => {
return 'test 입니다. test';
});
const instance = getCurrentInstance();
const router = instance.proxy.$router;
const store = instance.proxy.$store;
const route = instance.proxy.route;
let id = ref(store.state.writeInfo.id);
const back = () => {
router.back();
};
onMounted(() => {
console.log('onMounted');
});
return {
buttonClick,
User,
test1,
test2,
getLabel,
id,
back
};
}
};
</script>
외부 함수 import 하여 중복 코드 제거
import { ref, getCurrentInstance } from '@vue/composition-api';
export const Calculator = () => {
let instance = getCurrentInstance();
const router = instance.proxy.$router;
const store = instance.proxy.$store;
let version = ref('1.0');
let sum = (a, b) => {
return a + b;
};
let minus = (a, b) => {
return a - b;
};
return {
sum,
minus,
version
};
};
export default Calculator;
- 사용할 vue 파일
- 공통으로 사용할 함수인 Calculator 만들어 import 후 사용할 object 및 함수를 가져와서 현재 컴포넌트 화면에서 사용할 수 있다.
- Calculator의 특정 부분만 가져오기
let { sum, version } = Calculator();
<template>
<div>
<div>{{ version }}</div>
<div>{{ value }}</div>
</div>
</template>
<script>
import Calculator from '../composition/Calculator';
export default {
setup() {
let { sum, version } = Calculator();
let value = sum(2, 2);
return {
version,
value
};
}
};
</script>
- 변수에 담아서 호출 하는 방식
let calculator = Calculator();
<template>
<div>
<div>{{ version }}</div>
<div>{{ value }}</div>
</div>
</template>
<script>
import Calculator from '../composition/Calculator';
export default {
setup() {
let calculator = Calculator();
let value = calculator.sum(2, 2);
return {
version,
value
};
}
};
</script>
component props 전달 및 context emit
- 다른 컴포넌트에서 전달 받은 props의 데이터는 setup의 props로 전달 받을 수있다 아래
- emit을 통해 상위 컴포넌트로 데이터 전달 및 함수 호출 하려면 기존 this.$emit에서 context.emit으로 호출 이 가능 하다
export default {
props: {
showPoup: Boolean,
title: String,
bodyContent: String
},
setup(props, context) {
console.log('props.showPoup', props.showPoup);
console.log('props.title', props.title);
console.log('props.bodyContent', props.bodyContent);
let closePopup = () => {
context.emit('update:showPoup', false);
};
let onConfirmButton = () => {
closePopup();
context.emit('onButtonEvnet', true);
};
let onCancelButton = () => {
closePopup();
context.emit('onButtonEvnet', false);
};
return {
closePopup,
onConfirmButton,
onCancelButton
};
}
};
i18N 사용
setup(context) {
let i18n = getCurrentInstance().proxy.$i18n;
i18n.t('resource);
}