---
id: wiki-2026-0508-composition-api
title: Composition API (Vue 3)
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Vue Composition API, setup script]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [vue, composition-api, reactivity, frontend]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript
framework: Vue 3
---
# Composition API (Vue 3)
## 매 한 줄
> **"매 reactive primitive 으로 logic 을 조합한다"**. Composition API 는 Vue 3 의 `setup()` / `
```
### Typed props + emits + v-model
```vue
```
### reactive with toRefs (avoid losing reactivity)
```ts
import { reactive, toRefs } from 'vue';
export function useUser() {
const state = reactive({ name: 'Ada', age: 36 });
return { ...toRefs(state) }; // 매 destructurable + reactive
}
```
### watch with explicit source
```ts
import { ref, watch } from 'vue';
const query = ref('');
watch(query, async (q, _old, onCleanup) => {
const ctrl = new AbortController();
onCleanup(() => ctrl.abort());
const r = await fetch(`/search?q=${q}`, { signal: ctrl.signal });
// ...
});
```
### watchEffect (auto-track)
```ts
import { ref, watchEffect } from 'vue';
const userId = ref(1);
watchEffect(async () => {
const r = await fetch(`/api/users/${userId.value}`);
user.value = await r.json();
});
```
### Provide / inject (typed)
```ts
// keys.ts
import type { InjectionKey, Ref } from 'vue';
export const ThemeKey: InjectionKey[> = Symbol('theme');
// Parent
import { provide, ref } from 'vue';
const theme = ref<'light' | 'dark'>('dark');
provide(ThemeKey, theme);
// Child
import { inject } from 'vue';
const theme = inject(ThemeKey)!;
```
### Async setup with Suspense
```vue
```
### Lifecycle hooks
```ts
import { onMounted, onUnmounted } from 'vue';
onMounted(() => console.log('mounted'));
onUnmounted(() => console.log('cleanup'));
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| New Vue 3 project | Composition + `]