728x90
728x90
Vue.js에서 컴포넌트를 작성할 때 주로 사용하는 두 가지 방식인 Composition API와 Options API에 대해 다뤄보겠습니다. 이 두 가지는 Vue.js 개발에서 자주 비교되는 주제입니다. 각각의 특징, 장단점, 그리고 어떤 상황에서 유용한지를 자세히 살펴보고, 코드 예제와 함께 차이점을 분석해보겠습니다. Vue.js를 처음 접하는 사람부터 오랫동안 사용해온 개발자까지 참고할 수 있도록 가능한 한 명확하게 설명해보려 합니다.
1. Options API: 전통적인 Vue.js의 기반
먼저 Options API부터 시작해볼게요. Vue.js가 처음 세상에 나왔을 때부터 함께한 이 방식은 Vue 2.x 시절의 기본 접근법으로, 여전히 많은 개발자들에게 익숙하고 사랑받는 방식입니다. Options API는 이름 그대로 컴포넌트의 로직을 옵션 객체로 구성합니다. data, methods, computed, watch 같은 속성을 사용해 컴포넌트의 상태와 동작을 정의하죠.
Options API의 기본 구조
export default {
data() {
return {
count: 0,
message: "Hello, Vue!"
};
},
methods: {
increment() {
this.count++;
}
},
computed: {
doubleCount() {
return this.count * 2;
}
},
watch: {
count(newValue) {
console.log(`Count changed to ${newValue}`);
}
},
mounted() {
console.log("Component mounted!");
}
};
위 코드를 보면 알 수 있듯, Options API는 기능별로 로직을 분리합니다. 데이터는 data에, 메서드는 methods에, 계산된 값은 computed에, 생명주기 훅은 mounted 같은 곳에 각각 배치되죠. 이 구조는 직관적이고, 특히 작은 규모의 컴포넌트나 간단한 프로젝트에서는 매우 이해하기 쉽습니다.
장점
-
직관성과 단순함: 초보자가 코드를 읽고 작성하기에 매우 친화적입니다. 각 속성이 무엇을 의미하는지 명확하고, Vue의 핵심 개념을 배우기에 최적화되어 있어요.
-
구조화된 코드: 로직이 기능별로 나눠져 있어 작은 프로젝트에서는 유지보수가 쉬운 편입니다.
-
익숙함: Vue 2.x를 사용해온 개발자라면 이미 익숙한 방식이라 전환 비용이 없습니다.
단점
하지만 프로젝트가 커지면 문제가 생기기 시작합니다.
-
코드 분산: 하나의 기능(예: 카운터 로직)이 data, methods, computed, watch 등 여러 곳에 흩어지게 됩니다. 예를 들어, 사용자 프로필을 관리하는 로직이 있다고 하면, 관련 변수는 data에, 계산 로직은 computed에, 이벤트 핸들러는 methods에, 상태 변화를 감지하는 로직은 watch에 나뉘어 있어요. 이게 복잡해질수록 코드를 읽기가 힘들어집니다.
-
재사용성의 한계: 특정 로직을 다른 컴포넌트에서 재사용하려면 Mixin을 써야 하는데, Mixin은 이름 충돌이나 의존성 추적이 어려운 문제를 일으킬 수 있습니다.
-
타입스크립트와의 어색한 조합: Options API는 타입스크립트와 통합할 때 다소 불편한 점이 많아요. 타입 추론이 매끄럽지 않고, this의 타입을 명시적으로 정의해야 하는 경우가 많죠.
Options API는 작은 프로젝트나 빠르게 프로토타입을 만들 때 빛을 발하지만, 대규모 애플리케이션에서는 점점 한계를 드러냅니다. 그래서 등장한 것이 바로 Composition API입니다.
2. Composition API: Vue 3의 새로운 가능성
Vue 3에서 도입된 Composition API는 Options API의 단점을 보완하고, 더 유연하고 강력한 방식으로 컴포넌트를 작성할 수 있게 해줍니다. 이 방식은 함수 기반 접근법을 취하며, setup() 함수 안에 모든 로직을 정의합니다. 반응형 데이터, 메서드, 계산 속성 등을 하나의 흐름 안에서 관리할 수 있죠.
Composition API의 기본 구조
import { ref, computed, onMounted } from 'vue';
export default {
setup() {
// 반응형 데이터
const count = ref(0);
const message = ref("Hello, Vue!");
// 메서드
const increment = () => {
count.value++;
};
// 계산 속성
const doubleCount = computed(() => count.value * 2);
// 생명주기 훅
onMounted(() => {
console.log("Component mounted!");
});
// 반환
return {
count,
message,
increment,
doubleCount
};
}
};
Composition API는 setup() 함수 안에서 모든 것을 처리하고, 필요한 값과 함수를 반환해 템플릿에서 사용할 수 있게 만듭니다. ref와 reactive를 활용해 반응형 데이터를 정의하고, computed, watch, onMounted 같은 헬퍼 함수를 사용해 로직을 구성하죠.
장점
-
논리적 그룹화: 관련된 로직을 한 곳에 모을 수 있습니다. 예를 들어, 카운터와 관련된 모든 코드(상태, 메서드, 계산 속성)를 하나의 함수나 블록 안에 정리할 수 있어요. 이건 대규모 프로젝트에서 가독성을 크게 향상시킵니다.
-
재사용성: Composition API는 **컴포저블(composable)**이라는 재사용 가능한 로직 단위를 쉽게 만들 수 있게 해줍니다. 예를 들어, 마우스 위치를 추적하는 로직을 아래처럼 작성하고 여러 컴포넌트에서 재사용할 수 있죠.
import { ref, onMounted, onUnmounted } from 'vue'; export function useMousePosition() { const x = ref(0); const y = ref(0); const updatePosition = (e) => { x.value = e.pageX; y.value = e.pageY; }; onMounted(() => { window.addEventListener('mousemove', updatePosition); }); onUnmounted(() => { window.removeEventListener('mousemove', updatePosition); }); return { x, y }; } // 컴포넌트에서 사용 import { useMousePosition } from './composables/useMousePosition'; export default { setup() { const { x, y } = useMousePosition(); return { x, y }; } };
-
타입스크립트 친화적: Composition API는 함수 기반이라 타입스크립트와의 통합이 훨씬 자연스럽습니다. ref나 reactive 객체에 타입을 명시하기 쉽고, this에 의존하지 않으므로 타입 추론도 더 간단해요.
-
유연성: Options API처럼 정해진 구조에 얽매이지 않고, 개발자가 원하는 대로 로직을 구성할 수 있습니다.
단점
-
학습 곡선: Options API에 익숙한 개발자라면 처음에 약간 낯설게 느낄 수 있습니다. ref와 .value 사용법, reactive와의 차이 등을 익혀야 하죠.
-
보일러플레이트 코드: 작은 컴포넌트에서는 오히려 코드가 길어질 수 있어요. 예를 들어, 단순히 data에 넣으면 끝날 일을 ref로 정의하고 반환까지 해야 하니까요.
-
자유도 높은 만큼 책임도 커짐: 구조가 자유롭다 보니, 팀 단위로 일할 때 일관성을 유지하려면 별도의 가이드라인이 필요할 수 있습니다.
728x90
3. 언제 어떤 API를 써야 할까?
이제 두 API의 차이를 알았으니, 실제 프로젝트에서 어떤 걸 선택해야 할지 고민해보겠습니다.
Options API가 적합한 경우
-
소규모 프로젝트: 빠르게 프로토타입을 만들거나 간단한 앱을 개발할 때.
-
초보자: Vue.js를 처음 배우는 단계라면 Options API가 더 친절합니다.
-
기존 Vue 2 프로젝트: Vue 3로 마이그레이션했더라도 기존 코드베이스를 유지해야 한다면 Options API를 계속 사용할 수 있어요(Vue 3에서도 지원됩니다).
Composition API가 적합한 경우
-
대규모 프로젝트: 코드베이스가 커질수록 논리적 그룹화와 재사용성이 중요해지는데, 이때 Composition API가 빛을 발합니다.
-
타입스크립트 사용: 타입스크립트를 적극 활용한다면 Composition API가 훨씬 편리합니다.
-
재사용 가능한 로직: 공통 로직을 여러 컴포넌트에서 공유해야 할 때, 컴포저블을 활용한 Composition API가 유리합니다.
4. 두 API의 공존과 전환
Vue 3에서는 Options API와 Composition API가 공존합니다. 심지어 같은 컴포넌트 안에서 두 가지를 섞어 쓸 수도 있어요!
예를 들어:
import { ref, onMounted } from 'vue';
export default {
data() {
return {
message: "Hello from Options API!"
};
},
setup() {
const count = ref(0);
onMounted(() => {
console.log("Mounted via Composition API!");
});
return { count };
}
};
하지만 이런 혼합 사용은 가독성을 해칠 수 있으니, 팀 내에서 일관된 방식을 정하는 게 좋습니다.
Vue 2에서 Vue 3로 넘어오면서 Composition API를 도입해야 할지 고민이라면, 점진적인 전환을 추천드려요. 새로운 컴포넌트는 Composition API로 작성하고, 기존 코드는 필요할 때 리팩토링하는 식으로요.
728x90
5. 나에게 맞는 선택은?
결국 Composition API와 Options API 중 뭐가 더 좋다는 정답은 없습니다. 둘 다 Vue.js라는 멋진 프레임워크 안에서 각자의 역할을 하고 있죠. 개인적으로 저는 대규모 프로젝트와 타입스크립트를 다룰 때는 Composition API의 유연함에 끌리고, 빠르게 뭔가를 만들 때는 Options API의 단순함을 선호합니다.
여러분은 어떤 상황에서 어떤 방식을 선호하시나요? 댓글로 의견 남겨주시면 더 깊은 토론 이어가봐요! Vue.js의 매력은 이런 선택의 자유로움에서도 나오는 것 같아요. 그럼 다음 포스트에서 또 만나요!
728x90
728x90
'Vue.js 를 배워보자' 카테고리의 다른 글
Vue.js와 Nuxt.js의 라우팅 이해: 정적 vs 동적 로딩과 디렉토리 기반 라우팅 (0) | 2025.02.23 |
---|---|
Vue.js 컴포넌트 작성 스타일 비교: <script> + setup() vs <script setup> (0) | 2025.02.23 |
Vue 3 Composition API 완전 정복: ref, reactive, methods, v-model 그리고 스프레드 연산자 (2) | 2025.02.22 |
json-server를 Vue와 Nuxt에서 활용하는 방법: 실습과 예제로 풀어보기 (0) | 2025.02.21 |
Node.js, Express, JWT를 이용한 로그인 애플리케이션 구현하기 (0) | 2025.02.18 |