Vue 3 시작하기 — 기본 개념과 API 스타일
💡 [참고] Vue.js 관련 시리즈 포스트입니다. 순서대로 읽어보시길 권장합니다.
Vue 3를 처음 접할 때 가장 먼저 부딪히는 혼란이 있다. Options API와 Composition API 중 뭘 써야 하는가, <script setup>은 뭔가, SFC는 또 무엇인가. 이 글은 그 혼란을 정리하는 것에서 시작한다.
1. 개요
📌 Vue 3란?
Vue는 선언적 렌더링(Declarative Rendering) 과 컴포넌트 기반 설계를 지원하는 점진적(Progressive) JavaScript 프레임워크다.
💡 “점진적(Progressive)”이라는 말은 기존 HTML 파일에 script 태그 하나로 삽입해서 쓸 수도 있고, Vite + SFC 기반의 대규모 SPA로도 확장할 수 있다는 뜻이다.
Vue 3의 두 가지 핵심 특징:
| 특징 | 설명 |
|---|---|
| 선언적 렌더링 | JS 상태를 기반으로 HTML 출력을 선언적으로 기술. 상태 변경 시 DOM을 자동 업데이트 |
| 반응성(Reactivity) | JS 상태 변화를 자동 추적하여 효율적으로 DOM에 반영 |
📌 이 글의 구성
1
2
3
4
5
1. 개요 — Vue 3의 정의와 특징
2. 개념 설명 — SFC, Options API, Composition API 비교
3. 상세 구현 — 각 방식별 코드 예제
4. 정리 — 핵심 요약
5. 참고 자료 — 공식 문서 링크
2. 개념 설명
📌 Single-File Component (SFC)
SFC는 .vue 확장자를 가진 파일로, 하나의 파일 안에 템플릿(HTML), 로직(JS), 스타일(CSS)을 모두 담는다. 빌드 도구(Vite)가 있는 환경에서 권장되는 방식이다.
1
2
3
4
MyComponent.vue
├── <template> → HTML 구조
├── <script> → JS 로직
└── <style> → CSS 스타일
💡 SFC는 관심사를 하나의 파일로 캡슐화한다. 컴포넌트가 많아져도 파일 단위로 독립적으로 관리할 수 있어 유지보수가 쉽다.
📌 Options API vs Composition API
Vue 3는 두 가지 방식으로 컴포넌트를 작성할 수 있다.
| 구분 | Options API | Composition API |
|---|---|---|
| 방식 | data, methods, mounted 등 옵션 객체로 정의 | ref, onMounted 등 함수를 import하여 사용 |
this 사용 | O (컴포넌트 인스턴스를 this로 참조) | X (함수 스코프 변수 직접 사용) |
| 학습 곡선 | 낮음 (구조가 명확하게 정해져 있음) | 보통 (반응성 원리를 이해해야 함) |
| 로직 재사용 | Mixin (단점: 이름 충돌, 출처 불명확) | Composable 함수 (명확한 출처, 타입 추론 용이) |
| 권장 상황 | 빌드 도구 없이 사용, 간단한 시나리오 | 빌드 도구 + SFC, 대규모 애플리케이션 |
💡 Options API는 Composition API 위에 구현된 상위 레이어다. 내부적으로는 같은 반응성 시스템을 사용한다. (출처: vuejs.org/guide/introduction#api-styles)
3. 상세 구현
📌 최소 예제 — Options API
/**
- Options API는 컴포넌트 로직을 data, methods, lifecycle 옵션으로 분리한다.
- this를 통해 컴포넌트 인스턴스에 접근하며, OOP에 익숙한 개발자에게 친숙한 구조다. */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script>
export default {
// 반응형 상태: data()가 반환하는 객체의 프로퍼티가 반응형이 됨
data() {
return {
count: 0,
message: 'Hello Vue!'
}
},
// 메서드: 상태를 변경하거나 이벤트를 처리
methods: {
increment() {
this.count++ // this로 data에 접근
}
},
// 생명주기 훅: 컴포넌트가 마운트될 때 실행
mounted() {
console.log(`초기 count: ${this.count}`)
}
}
</script>
<template>
<button @click="increment">
Count: 9
</button>
</template>
📌 최소 예제 — Composition API + <script setup>
/**
- Composition API는 반응형 상태와 로직을 함수 스코프에서 직접 선언한다.
- 별도의 return 없이 선언한 모든 변수와 함수를 템플릿에서 바로 사용할 수 있다. */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script setup>
import { ref, onMounted } from 'vue'
// ref(): 원시값을 반응형으로 만든다
const count = ref(0)
const message = ref('Hello Vue!')
// 일반 함수로 로직을 정의 (this 불필요)
function increment() {
count.value++ // <script> 내부에서는 .value로 접근
}
// 생명주기 훅을 함수로 등록
onMounted(() => {
console.log(`초기 count: ${count.value}`)
})
</script>
<template>
<!-- 템플릿 안에서는 .value 없이 자동 언래핑 -->
<button @click="increment">
Count: 9
</button>
</template>
📌 <script setup>이 왜 권장되는가
<script setup>을 사용하면 컴파일 타임 변환이 적용되어 보일러플레이트가 줄어든다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 일반 Composition API: return 필요 -->
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
return { count } // 템플릿에 노출하려면 명시적 return 필요
}
}
</script>
<!-- <script setup>: return 불필요 -->
<script setup>
import { ref } from 'vue'
const count = ref(0) // 선언만 해도 템플릿에서 바로 사용 가능
</script>
📌 반응성 동작 확인
/**
- Vue 3의 반응성 시스템은 ES6 Proxy 기반으로 동작한다.
- 상태가 변경되면 Vue가 이를 자동으로 감지하고 DOM을 업데이트한다.
- 아래 예제는 반응성이 실제로 어떻게 동작하는지 보여준다. */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script setup>
import { ref, reactive, computed } from 'vue'
// ref: 원시값 (number, string, boolean)
const count = ref(0)
// reactive: 객체 전체를 반응형으로
const user = reactive({
name: 'Chan',
role: 'developer'
})
// computed: 다른 반응형 상태를 기반으로 파생된 값
// count나 user.name이 바뀔 때만 재계산된다
const summary = computed(() => {
return `${user.name} (${user.role}): ${count.value}번 클릭`
})
</script>
<template>
<p></p>
<button @click="count++">클릭</button>
<input v-model="user.name" placeholder="이름 변경" />
</template>
4. 정리
- Vue 3는 선언적 렌더링과 반응성 시스템을 기반으로 한다. 상태가 바뀌면 DOM은 자동으로 업데이트된다.
- SFC(
.vue파일)는 template/script/style을 하나의 파일로 캡슐화하며, 빌드 도구 환경에서 권장된다. - Options API와 Composition API는 같은 반응성 시스템 위에서 동작하는 두 가지 작성 방식이다.
- 프로덕션 + SFC 환경에서는 Composition API +
<script setup>조합이 공식 권장 방식이다. ref()는.value로 접근하며, 템플릿 안에서는 자동 언래핑된다.