Vanilla JS에서 re-usealbe한 코드를 작성하려면 어떻게 할까? 중복되는 코드를 덜어서 그냥 함수를 생성하면 된다.
즉, JS는 일반적으로 함수를 통해 기능을 공유하고 아웃소싱한다.
그리고 Composition API의 setup은 그저 여러 로직을 뭉쳐놓은 하나의 메서드일 뿐이다.
이는 일반 JS과 같이 아웃소싱하려는 함수를 만들어주면 된다는 것이다.
Options API에서는 이게 안 되는 이유가 옵션 API에서는 여러 단계를 뭉쳐놓은 하나의 메서드가 아니라 여러 프로퍼티가 포함된 객체였기 때문이었다.
hook
이라고도 하기 때문이다.컴포지션 API에서 이 특수 함수의 이름으로 또 뭐라고 부를 수 있을 까?
커스텀 컴포지션 함수나 컴포저블이라고도 할 수 있다.
즉,hook
,composable
,custom Composition function
다 같은 것이다.
use-
로 시작해야한다. 그리고 이러한 개념은 react custom hooks와 굉장히 유사하다.import {ref} from "vue";
const useAlert = () => {
const alertIsVisible = ref(false);
const showAlert = () => {
alertIsVisible.value = true
}
const hideAlert = () => {
alertIsVisible.value = false;
}
return {alertIsVisible, showAlert, hideAlert}
}
export default useAlert
이때 반환값은 반드시 존재해야한다.
그리고 해당 훅을 사용할 컴포넌트에서 구조분해로 가져오면 된다.
<template>
<user-alert v-if="alertIsVisible" title="Add a User?" @close="hideAlert">
<p>Do you want to continue with adding a user?</p>
</user-alert>
<section>
<h2>Add a User</h2>
<button @click="showAlert">Add User</button>
</section>
</template>
<script setup>
import UserAlert from './UserAlert.vue';
import useAlert from "@/hooks/alert";
const {alertIsVisible, showAlert, hideAlert} = useAlert();
</script>
그리고 구조분해는 배열도 가능하여 배열로 작성해도 무관하다 배열특성상 순서를 반드시 지켜야하기 때문에 나는 개체로 구조분해하였다.
그리고 당연하게 훅을 통해 넘어온 값이 원래가 ref라면 넘어온 값 역시 반응형이 된다. 이는 훅 내부에서 값이 변경될 때 마다
해당 훅을 사용하는 컴포넌트가 그에 대한 알림을 받는다.
그리고 Vue가 알아서 템플릿에 반영해준다. 즉, 따로 computed 메서드를 사용하지 않아도 된다는 것이다.
import {ref} from "vue";
const useAlert = (setVisible=false) => {
const alertIsVisible = ref(setVisible);
const showAlert = () => {
alertIsVisible.value = true
}
const hideAlert = () => {
alertIsVisible.value = false;
}
return {alertIsVisible, showAlert, hideAlert}
}
export default useAlert
<template>
<user-alert v-if="alertIsVisible" title="Add a User?" @close="hideAlert">
<p>Do you want to continue with adding a user?</p>
</user-alert>
<section>
<h2>Add a User</h2>
<button @click="showAlert">Add User</button>
</section>
</template>
<script setup>
import UserAlert from './UserAlert.vue';
import useAlert from "@/hooks/alert";
const {alertIsVisible, showAlert, hideAlert} = useAlert(true);
</script>
물론 위같이 작성하면 alert 모달창이 처음부터 튀어나와 이상하겠지만 우선 개념을 이해하는데에 있어서는 그만이다.
여기서 말하고자 하는 것은 우리가 필요한 인수를 어느 것이든 취해서 모든 컴포지션 API 기능을 훅에 사용할 수 있다는 것이다.
훅이 해야 할 작업을 수행한 후 해당 훅을 활용해야 하는 컴포넌트에 결과를 반환할 수 있다.