Vue 3 시작하기
Vue는 "점진적 프레임워크(Progressive Framework)"입니다. 필요한 만큼만 도입하고, 프로젝트가 커지면 그때 확장하면 됩니다.
면접에서 "왜 Vue를 선택했나요?"라는 질문을 받았을 때, "쉬워서요"보다 훨씬 좋은 대답이 있습니다. Vue 3의 설계 철학과 핵심 특징을 제대로 이해하면 자연스럽게 답할 수 있습니다.
Vue 3란?
Vue.js는 사용자 인터페이스를 구축하기 위한 JavaScript 프레임워크입니다. Vue 3는 2020년에 출시된 메이저 버전으로, 다음과 같은 핵심 변화가 있었습니다.
- Composition API 도입 — 로직 재사용성과 코드 구성이 획기적으로 개선
- Proxy 기반 반응형 시스템 — Vue 2의
Object.defineProperty한계 극복 - Tree-shaking 지원 — 사용하지 않는 기능은 번들에서 제거
- TypeScript 네이티브 지원 — 프레임워크 자체가 TypeScript로 작성
프로젝트 생성
Vue 3 프로젝트를 만드는 공식 방법은 create-vue입니다.
# 최신 프로젝트 스캐폴딩 도구
npm create vue@latest
# 프로젝트명 입력 후 옵션 선택
# - TypeScript? Yes
# - JSX? No
# - Vue Router? Yes
# - Pinia? Yes
# - Vitest? Yes
# - ESLint + Prettier? Yes
생성된 프로젝트 구조를 살펴보겠습니다.
my-vue-app/
├── public/
│ └── favicon.ico
├── src/
│ ├── assets/ # 정적 리소스
│ ├── components/ # 재사용 컴포넌트
│ ├── router/ # 라우터 설정
│ ├── stores/ # Pinia 스토어
│ ├── views/ # 페이지 컴포넌트
│ ├── App.vue # 루트 컴포넌트
│ └── main.ts # 앱 진입점
├── index.html
├── package.json
├── tsconfig.json
└── vite.config.ts
앱 진입점 이해하기
// main.ts — 앱의 시작점
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
// 앱 인스턴스 생성
const app = createApp(App)
// 플러그인 등록
app.use(router)
app.use(createPinia())
// DOM에 마운트
app.mount('#app')
createApp은 Vue 3에서 도입된 팩토리 함수입니다. Vue 2에서는 new Vue()를 사용했는데, 전역 설정이 모든 인스턴스에 영향을 줘서 테스트가 어려웠습니다. createApp은 인스턴스별로 독립적인 설정을 가능하게 합니다.
첫 번째 컴포넌트
Vue의 Single File Component(SFC)는 .vue 확장자를 사용합니다.
<script setup lang="ts">
// script setup — Composition API의 간결한 문법
import { ref } from 'vue'
// 반응형 상태 선언
const message = ref('안녕하세요, Vue 3!')
const count = ref(0)
// 메서드 정의
const increment = () => {
count.value++
}
</script>
<template>
<!-- 템플릿 — UI 구조를 선언적으로 작성 -->
<div>
<h1>{{ message }}</h1>
<p>카운트: {{ count }}</p>
<button @click="increment">증가</button>
</div>
</template>
<style scoped>
/* scoped — 이 컴포넌트에만 적용되는 스타일 */
h1 {
color: #42b883;
}
button {
padding: 8px 16px;
background-color: #42b883;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
SFC의 세 가지 블록
| 블록 | 역할 | 필수 여부 |
|---|---|---|
<script setup> | 컴포넌트 로직 (상태, 메서드, 생명주기) | 선택 |
<template> | UI 구조 (HTML + Vue 디렉티브) | 필수 |
<style> | 스타일링 (scoped로 범위 제한 가능) | 선택 |
Vue 2 vs Vue 3 — 면접에서 자주 묻는 차이점
| 항목 | Vue 2 | Vue 3 |
|---|---|---|
| 반응형 시스템 | Object.defineProperty | Proxy |
| API 스타일 | Options API만 | Options + Composition API |
| 루트 엘리먼트 | 하나만 허용 | 다중 루트(Fragment) 허용 |
| 앱 생성 | new Vue() | createApp() |
| TypeScript | 제한적 지원 | 네이티브 지원 |
| 번들 크기 | ~23KB (min+gzip) | ~16KB (min+gzip) |
면접에서 이 차이를 물어보면 단순 나열보다 "왜 바뀌었는지" 를 설명하는 것이 좋습니다. 예를 들어 "Proxy를 사용하면 배열 인덱스 변경이나 새 속성 추가도 자동으로 감지됩니다"처럼요.
Vite — Vue 3의 기본 빌드 도구
Vue 3는 Vite를 기본 빌드 도구로 사용합니다. Vite의 장점을 알아두면 좋습니다.
- 즉시 서버 시작 — ESM 기반으로 번들링 없이 서버 시작
- HMR(Hot Module Replacement) — 파일 변경 시 밀리초 단위로 반영
- ** 최적화된 빌드** — 프로덕션 빌드 시 Rollup 사용
# 개발 서버 실행
npm run dev
# 프로덕션 빌드
npm run build
# 빌드 결과 미리보기
npm run preview
개발 도구(DevTools)
Vue DevTools는 디버깅에 필수적인 브라우저 확장입니다.
- ** 컴포넌트 트리** 확인 — 계층 구조와 각 컴포넌트의 상태를 실시간 조회
- Pinia 스토어 상태 추적
- ** 라우터** 현재 경로와 매칭된 컴포넌트 확인
- ** 타임라인** — 이벤트 발생 순서 추적
Chrome이나 Firefox 확장으로 설치할 수 있고, 독립 실행형 앱으로도 사용 가능합니다.
면접 팁
- "Vue의 점진적 프레임워크 철학"을 설명할 수 있어야 합니다 — CDN 스크립트 태그 하나로 시작해서, 필요하면 라우터, 상태 관리, 빌드 도구를 단계적으로 추가할 수 있다는 의미입니다
createApp과new Vue()의 차이는 ** 앱 인스턴스 격리** 관점에서 설명하면 깊이 있어 보입니다- Vue 3의 Proxy 기반 반응형이 Vue 2의 한계를 어떻게 해결하는지 한두 문장으로 정리해두세요
요약
Vue 3는 Composition API, Proxy 반응형, TypeScript 네이티브 지원이라는 세 가지 축으로 Vue 2의 한계를 극복했습니다. create-vue로 프로젝트를 생성하고, SFC 구조(script setup + template + style)로 컴포넌트를 작성하는 것이 기본 워크플로입니다.