Option API에서 Composition API로의 전환

Mincho·2023년 9월 22일
1

[Vue]

목록 보기
2/3

Vue에서의 로직 관리

 vue.js에서는 vue를 구성요소를 구축하는 방식이 필요했습니다. 이러한 구성 요소의 구성은 React는 useState를 이용한 상태관리, useEffect를 이용한 컴포넌트의 생명주기를 예를 들 수 있습니다. 이러한 함수형 컴포넌트 구성 이전에는 class기반을 한 생명주기 메서드들을 사용하여 관리되곤 하였습니다.

 Vue에서도 이러한 생명주기 메서드들을 포함하여 상태관리 데이터 바인딩에 대한 솔루션을 제공하고 있습니다. 바로 Option API와 Composition API가 그 예시라고 볼 수 있습니다.


Option API / Composition API

 기존의 Vue2까지는 전통적인 방식의 Option API방식으로 구성 요소를 구축하였습니다. 그러나 Vue3 출시 이후 Composition API 출시 후 개발자들 간에 뜨거운 주제로 떠올랐습니다. Composition API를 사용하게 되면 객체지향의 Class기반 보다는 함수형 프로그래밍의 느낌을 받으시게 됩니다. 저의 경우에도 this의 문법을 알고는 있지만 실제로 응용하여 적용해본 경험이 적기 때문에 익숙하지 않았지만 Compostion API를 사용하게 되면서 좀 더 편의성을 느끼게 되었습니다.

//OptionAPI
<script>
  export default{
	data(){
    	return{
          const cnt = 0
        }
    },
	methods: {
    	plus() {
     		this.count++
    }
  },
}
</script>

<template>
  <button @click="plus()">숫자: {{ cnt }}</button>
</template>
//CompositionAPI
<script>
import { ref, onMounted } from 'vue'

setup () {
	// 반응형
	const cnt = ref(0)
	const plus = () => { cnt.value++ }

	// 생명주기 훅
	onMounted(() => { console.log(`mounted`) })
}

</script>

<template>
  <button @click="plus()">숫자: {{ cnt }}</button>
</template>

 composition API는 옵션을 선언하는 대신 가져온 함수를 사용하여 구성 요소를 정의합니다. 원시값은 ref(), 참조값은 reactive()로 반응형 API를 제공하며, onMounted/onUnmounted로 구성요소 라이프사이클을 연결할 수 있습니다.


Composition API로 전환 이유

확장성 측면

 처음 Option API를 사용했을 때는 data면 data, method면 method, watch면 watch로 로직을 모아놓을 수 있어서 좋다고 생각하였습니다. 하지만 확장성 면에서 피곤한 점이 많았습니다. data나 method 등을 구분 없이 논리적 흐름대로 묶어 놓거나 변경하는데 어려움이 따라왔습니다. 특히 특정 라이브러리를 사용할 때도 Compostion API환경에서 세팅되는 것을 선호하기도 하였습니다. 기존환경에서는 추가로 세팅해야하는 부분이 있었습니다.

Vue-Query공식문서에서의 Compostion API에서의 세팅.

타입 추론과 코드 단축 측면

 프론트엔드 언어로 TypeScript를 점점 채택하고 있는 추세입니다. 그러나 Option API는 이러한 타입 추론을 염두하지 않고 설계되었습니다. 이에 비해 Compostion API는 대부분 타입 친화적인 코딩이 가능해졌습니다.

 또한 Composition API로 작성된 코드는 <script setup>을 통해 효율적인 코드 작성을 할 수 있습니다.

<script setup>
import QuizCard from "../../components/card/QuizCard.vue";
import { useQuery } from "@tanstack/vue-query";
import { getQuizData } from "../../utils/api/axiosSetting";
import { useRoute, useRouter } from "vue-router";

const router = useRouter();
const route = useRoute();

const category = route.params.category;

/**Quiz Data Fetching */
const { data: quizDatas = [] } = useQuery(
  ["quizData"],
  () => getQuizData(category),
  {
    onError: () => {
      router.push("/error");
    },
    retry: false,
  }
);
</script>

<template>
  <QuizCard
    v-for="(quizData, index) in quizDatas"
    :key="quizData.id"
    :quizId="quizData.id"
    :pk="index"
    :question="quizData.question"
    :options="quizData.options"
    :answer="quizData.answer"
    :answerDescription="quizData.answerDescription"
    :quizLength="quizDatas.length"
    :quizType="quizData.quizType"
    :answerRate="quizData.answerRate"
  />
</template>

 위의 코드는 제가 직접 Vue프로젝트를 진행했을 때 작성했던 코드입니다. QuizCard컴포넌트를 가져올때 한번더 component를 명명해주지 않아도 되고 router나 함수를 자유롭게 정의하고 사용할 수 있습니다. React를 사용하신 분이라면 뭔가 익숙하시다고 느끼실 수 있습니다.

React Hooks와의 비교

 Compostion API는 React Hooks와 동일한 수준의 논리 구성 기능을 제공하지만 차이를 보이고 있습니다. React Hooks는 구성 요소가 없데이트 될 때마다 반복적인 호출을 하고 있습니다. 예를 들어 React에서 상태를 변경 할 때, useEffect에서 의존성 배열에 대한 값 감시, 부모 컴포넌트 리렌더링 등으로 의도치 않은 성능 저하가 일어날 수 있습니다. 이를 위해 useMemo나 useCallback등으로 업데이트를 최소하할 수 있지만 비용이 많이 드는 문제입니다.

 Vue의 반응형 시스템은 종속성을 자동을 수집하기 때문에 억지로 종속성을 수동으로 선언할 필요가 없습니다. 또한 불필요한 리레던더링을 막기 위해 콜백 함수를 통해 캐시할 필요가 없습니다. 일반적으로 Vue는 반응형 시스템을 위해 하위 구성요소가 필요할 때만 업데이트되도록 보장합니다. 이 때문에 불가피한 성능 저하를 최소화할 수 있게 되었습니다.


Reference
https://vuejs.org/guide/extras/composition-api-faq.html#comparison-with-react-hooks
https://vueschool.io/articles/vuejs-tutorials/options-api-vs-composition-api/![](https://velog.velcdn.com/images/chhw130/post/d46a9d0a-b000-4989-888a-cfab81a9a661/image.png)

👍올바른 피드백은 언제든지 환영입니다~!

profile
www.mincho130.xyz <-- 블로그 이사했습니당

0개의 댓글