---
id: wiki-20260508-composition-api-redir
title: Composition API
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Vue Composition API, setup()]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
verification_status: applied
tags: [vue, reactivity, frontend]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: TypeScript
  framework: Vue 3
---

# Composition API

## 매 한 줄
> **"매 logic-by-feature, not-by-option"**. 매 Vue 2 의 Options API (data/computed/methods 의 monolithic blob) 의 limitation 매 large component 의 reuse 의 difficulty → 매 Vue 3 (2020) 의 setup-function-based, ref/reactive primitive, custom-composables 의 pattern.

## 매 핵심

### 매 primitives
- `ref<T>(initial)` — 매 single value reactive container, `.value` access.
- `reactive<T>(obj)` — 매 deep proxy 의 object.
- `computed(() => ...)` — 매 lazy + cached derived.
- `watch(source, cb)` — 매 reactive side-effect.
- `watchEffect(cb)` — 매 auto-track dependencies.

### 매 modern (Vue 3.4+ / 2026)
- `<script setup>` SFC syntax (default in Vue 3.2+).
- `defineProps`, `defineEmits`, `defineExpose`, `defineModel` (3.4).
- Reactivity Transform 매 deprecated → 매 macros 의 explicit `.value`.

### 매 응용
1. Custom composables (replace mixins).
2. Cross-component state via VueUse / Pinia.
3. Type-safe props/emits via `defineProps<T>()`.

## 💻 패턴

### `<script setup>` baseline
```vue
<script setup lang="ts">
import { ref, computed } from 'vue';
const count = ref(0);
const double = computed(() => count.value * 2);
const inc = () => count.value++;
</script>

<template>
  <button @click="inc">{{ count }} (×2 = {{ double }})</button>
</template>
```

### Custom composable
```ts
// useCounter.ts
import { ref, computed } from 'vue';

export function useCounter(initial = 0, step = 1) {
  const count = ref(initial);
  const double = computed(() => count.value * 2);
  const inc = () => (count.value += step);
  const reset = () => (count.value = initial);
  return { count, double, inc, reset };
}
```

### Async data with `useFetch` (VueUse)
```ts
import { useFetch } from '@vueuse/core';
const { data, error, isFetching } = useFetch<User[]>('/api/users').json();
```

### `defineModel` (Vue 3.4)
```vue
<script setup lang="ts">
const model = defineModel<string>({ required: true });
</script>
<template>
  <input v-model="model" />
</template>
```

### `watch` + `watchEffect`
```ts
import { watch, watchEffect } from 'vue';
watch(count, (v, old) => console.log('count', old, '→', v));
watchEffect(() => console.log('auto-tracks', count.value));
```

### Provide/Inject typed
```ts
// parent
import { provide } from 'vue';
import type { InjectionKey } from 'vue';
const ThemeKey: InjectionKey<Ref<'light' | 'dark'>> = Symbol();
provide(ThemeKey, theme);

// child
import { inject } from 'vue';
const theme = inject(ThemeKey, ref('light'));
```

## 매 결정 기준
| 상황 | API |
|---|---|
| Vue 2 legacy | Options API |
| Vue 3 new code | Composition API + `<script setup>` |
| Cross-component state | Pinia (composition-style) |

**기본값**: `<script setup>` + composables + Pinia.

## 🔗 Graph
- 부모: [[Vue]]
- 변형: [[Options-API]] · [[Reactivity-Transform]]
- 응용: [[VueUse]] · [[Pinia]]
- Adjacent: [[React-Hooks]] · [[Solid-Signals]]

## 🤖 LLM 활용
**언제**: Vue 3+ component logic, reusable stateful logic, TS-first SFCs.
**언제 X**: Vue 2 codebase 매 still on Options API; team unfamiliar with reactivity primitives.

## ❌ 안티패턴
- **Forgetting `.value` on refs**: 매 silently broken reactivity.
- **Destructuring `reactive()` 의 result**: 매 loses reactivity (use `toRefs`).
- **Mega-`setup()`**: 매 extract composables.

## 🧪 검증 / 중복
- Verified (vuejs.org/api/composition-api-setup.html, Vue 3.4 release notes).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Composition API FULL Vue 3.4+ patterns |
