Vue.js의 Composition API는 Vue 3에서 가장 핵심적이고 근본적인 변화 중 하나입니다. 이전 방식인 Options API가 가진 구조적인 한계를 극복하고, 대규모 애플리케이션 개발의 생산성과 가독성을 혁신적으로 개선한 패턴이라고 이해하시면 됩니다.
아래에서 Composition API가 무엇인지, 왜 필요한지, 그리고 핵심 구성 요소들을 매우 상세하게 설명드리겠습니다.
🚀 1. Composition API란 무엇인가? (개념 정의)
Composition API는 Vue 컴포넌트 내에서 관련된 로직(State, Logic, Side Effect)들을 시간적 순서에 관계없이, 기능별(Feature-based)로 그룹화하여 작성하는 방식을 의미합니다.
🔍 Options API와의 근본적인 차이점
| 특징 | Options API (기존 방식) | Composition API (새로운 방식) |
|---|---|---|
| 로직 분리 방식 | 관심사별(Concern-based)로 분리 (data, methods, computed, watch 등) |
기능별(Feature-based)로 그룹화 |
| 문제점 | 로직이 길어지면, 하나의 기능을 구현하는 코드가 methods와 computed 등 여러 섹션에 분산되어 코드를 따라가기 어렵다 (분산성 문제). |
관련 로직을 하나의 묶음으로 응집시켜서 관리하기 매우 쉽다. |
| 핵심 도구 | 키워드 기반 (Options: data: {}, methods: {}) |
|
함수 기반 (Hooks: setup(), ref(), computed()) |
||
| 적합한 상황 | 작고 단순한 컴포넌트. | 크고 복잡하며 비즈니스 로직이 복잡한 대규모 컴포넌트. |
핵심 요약: Options API가 "데이터 관리는 data에, 함수 처리는 methods에"와 같이 "어디에 넣을지"를 구조적으로 강제했다면, Composition API는 "이 기능에 필요한 모든 로직을 한곳에 모아 놓자"에 초점을 맞춘 접근 방식입니다.
🧱 2. Composition API의 핵심 구조와 도구
Composition API를 사용한다는 것은, 컴포넌트의 라이프사이클(setup() 함수) 내부에서 Vue에서 제공하는 특정 함수(Hooks)들을 호출하여 상태(State)와 반응성(Reactivity)을 관리한다는 의미입니다
.
🥇 2-1. setup() 함수 (진입점)
Vue 3 컴포넌트는 export default 구조 대신 함수 컴포넌트 구조를 사용하며, 모든 반응성 로직은 이 setup() 함수 내에서 시작됩니다.
- 역할: 컴포넌트가 마운트되기 직전에 실행되는 초기화 지점입니다. 모든
ref,reactive등의 코드가 여기에 위치합니다. - 특징: 컴포넌트의
<script setup>문법을 사용하면 이setup()을 명시적으로 작성하지 않아도 됩니다.
🥈 2-2. 반응성(Reactivity) 시스템 (가장 중요!)
Composition API의 근간은 Vue의 반응성 시스템입니다. 자바스크립트의 일반 변수(let count = 0)를 쓰면 값이 변해도 화면이 자동으로 업데이트되지 않습니다. 우리는 변화에 반응하는 변수를 사용해야 합니다
.
① ref(): 기본형(Primitive) 데이터를 위한 반응성 객체
- 사용처: 숫자, 문자열, 불리언 등 원시 타입(Primitive Type)을 감쌀 때 사용합니다.
- 작동 원리:
ref로 감싼 변수를 반드시.value를 통해 접근하고 변경해야 합니다. - 예시:
import { ref } from 'vue'; const count = ref(0); // count는 단순 변수가 아니라 ref 객체입니다. // 화면에서 사용하거나 변경할 때는 count.value를 써야 합니다.
② reactive(): 객체(Object) 데이터를 위한 반응성 객체
- 사용처: 여러 속성을 가진 객체(Object) 자체를 감쌀 때 사용합니다.
- 작동 원리: 객체 전체를 감싸기 때문에, 속성 접근 시에는 일반적인 JavaScript 객체처럼
state.name방식으로 접근할 수 있습니다. - 예시:
import { reactive } from 'vue'; const state = reactive({ name: 'VueUser', age: 30 }); // 접근 및 변경: state.name = 'NewName'
💡
refvsreactive선택 가이드:
- 가장 안전하고 권장되는 패턴: 원시 타입은
ref, 객체 타입은reactive를 사용하되, 로직의 통일성을 위해 필요한 경우 모든 것을ref로 감쌀 수도 있습니다.- 실습 팁: 초보자라면 원시 타입을 다룰 때나 명확한 구조가 필요할 때
ref()사용을 습관화하는 것이 좋습니다.
🥉 2-3. computed(): 파생 상태(Derived State)
- 역할: 다른 반응형 상태(
ref나reactive)를 기반으로 계산되지만, 스스로 변경되지 않는 상태를 만들 때 사용합니다. - 특징: 이 값을 가져올 때만 계산하고, 값이 변경되었을 때만 재계산됩니다. (캐싱 효과)
- 예시: 사용자 이름과 성을 조합하여 '전체 이름'을 계산할 때.
import { computed } from 'vue'; const firstName = ref('John'); const lastName = ref('Doe'); const fullName = computed(() => `${firstName.value} ${lastName.value}`); // firstName이 바뀌면, fullName도 자동으로 업데이트됩니다.
🏅 2-4. watch / watchEffect: 부수 효과(Side Effect) 처리
- 역할: 특정 반응성 상태(State)가 변경되었을 때 "어떤 동작"을 수행해야 할 때 사용합니다. (예: 로컬스토리지 저장, API 호출, 메시지 띄우기 등)
watch(source, callback): 특정 변수나 Getter를 지정하고, 그것이 변경될 때마다 콜백 함수를 실행합니다.watchEffect(callback): 콜백 함수 내부에서 사용된 모든 반응형 상태를 감지하여, 초기 실행 후 상태가 변경될 때마다 자동으로 콜백을 재실행합니다. (설정할 변수가 복잡하지 않을 때 유용)- 예시:
count가 10이 될 때마다 API 호출을 수행.
✨ 2-5. onMounted 등 라이프사이클 훅 (Hooks)
Composition API는 Options API의 라이프사이클 훅을 함수 형태로 사용합니다.
onMounted(() => { ... }): 컴포넌트가 DOM에 성공적으로 마운트된 후에 실행할 로직을 넣습니다. (예: API 호출)onUpdated(() => { ... }): 컴포넌트의 반응형 데이터가 변경되어 DOM이 업데이트된 후에 실행합니다.onUnmounted(() => { ... }): 컴포넌트가 파괴되기 직전에 실행하며, 구독 해지(Cleanup) 로직을 넣을 때 필수적입니다.
🧩 3. 가장 강력한 이점: Custom Composables (커스텀 훅)
Composition API를 배운 이유 중 90%는 바로 이 Custom Composables를 만들기 위해서입니다.
커스텀 훅이란, 특정 기능을 재사용할 수 있도록 setup() 함수와 ref, reactive 같은 훅들을 묶어 별도의 파일(.js 또는 .ts)로 추출한 함수를 말합니다. (React의 Custom Hook과 개념적으로 동일합니다.)
🛠️ 사용 예시: useFetch.js
만약 데이터 가져오기, 로딩 상태 관리, 에러 처리 로직이 3개의 다른 컴포넌트에서 반복된다고 가정해 봅시다.
Options API였다면: 각 컴포넌트의 <script> 블록에 isLoading, data, fetchData 로직을 각자 구현하고, 중복 코드가 발생했을 겁니다.
Composition API를 사용한다면:
useFetch.js파일에 데이터 패칭 로직 전체를 정의합니다.- 컴포넌트에서 이 훅을 불러옵니다.
// MyComponent.vue <script setup> import { useFetch } from '@/composables/useFetch'; // 데이터와 로직이 깔끔하게 분리되고, 컴포넌트는 그 결과를 사용만 하면 됩니다. const { data, isLoading, error } = useFetch('/api/user/' + userId); </script>
결과:
- 재사용성: 비즈니스 로직(State, Logic)을 100% 분리하여 여러 컴포넌트에서 재사용할 수 있습니다.
- 가독성: 컴포넌트의 로직이 "무엇을 하는지" (What)에 초점을 맞추고, "어떻게 구현되었는지" (How)는 훅 내부로 숨기게 되어 코드가 매우 깔끔해집니다.
📝 요약 정리 (최종 점검)
| 개념 | 목적 | 핵심 코드 | 대체 역할 (Options API) |
|---|---|---|---|
| Composition API | 관련 로직을 기능별로 그룹화. | setup() 내부의 함수 호출 |
Options 블록 전체 |
ref() |
원시형 상태를 반응형으로 만듦. | const count = ref(0) |
data() 속성 |
reactive() |
객체 상태를 반응형으로 만듦. | const state = reactive({}) |
data() 속성 |
computed() |
상태를 기반으로 파생되는 값을 계산. | const fullName = computed(...) |
computed 속성 |
watch() |
상태 변경에 따른 부수 효과 처리. | watch(source, callback) |
watch 속성 |
onMounted() |
컴포넌트 마운트 시점의 초기화. | onMounted(() => { ... }) |
mounted() 훅 |
| Composables | 복잡한 로직을 외부 파일로 분리하여 재사용. | useSomething.js |
없음 (이것이 가장 큰 이점) |
'IT프리랜서' 카테고리의 다른 글
| 다가올 2026년, IT 기업의 생존을 위협하는 사이버 위협 리포트 (0) | 2026.05.04 |
|---|---|
| 2026년 IT 보안, 어떤 위협에 주목해야 할까? (0) | 2026.05.03 |
| 블로그 썸네일 걱정 끝! Felo LiveDoc으로 문서 내용에 맞는 삽화 자동 생성하기 (0) | 2026.02.08 |
| 미드저니 대신 무료로? Felo AI로 고퀄리티 이미지 3초 만에 만들기 (사용법 포함) (0) | 2026.02.07 |
| "개발자는 이제 설계자다" 2026년 바이브 코딩이 바꾼 개발자의 현실 (0) | 2026.02.05 |