단일 파일 컴포넌트와 반응형 상태의 기초.
Vue 시작하기 (SFC)
Vue는 SFC(Single File Component) 한 파일에 template·script·style을 함께 담아 컴포넌트를 만듭니다. 화면을 작은 부품(컴포넌트) 단위로 쪼개고, 데이터가 바뀌면 화면이 알아서 다시 그려지는 반응형(reactive) 방식이 핵심입니다. 이번 강좌는 Vue 3 + Composition API(<script setup>)를 기준으로 진행합니다.
학습 목표
- SFC가
template·script setup·style scoped세 블록으로 이루어진다는 걸 이해한다. ref로 반응형 상태를 만들고.value로 다루는 법을 익힌다.- 디렉티브가 무엇인지, 대표적인 것들의 역할을 파악한다.
첫 컴포넌트
<script setup>
import { ref } from 'vue';
const count = ref(0);
const increment = () => count.value++;
</script>
<template>
<button @click="increment">
{{ count }} 번 클릭
</button>
</template>
<style scoped>
button { padding: 8px 16px; }
</style>
위 파일 하나가 곧 하나의 컴포넌트입니다. 세 블록은 각각 이런 역할을 합니다.
<template>— 화면에 보이는 HTML 구조. 데이터를 끼워 넣거나 디렉티브로 동작을 붙입니다.<script setup>— 컴포넌트의 로직. 상태·함수를 선언하면template에서 바로 쓸 수 있습니다.<style scoped>— 스타일.scoped를 붙이면 이 컴포넌트 안에서만 적용되어 다른 곳에 새지 않습니다.
💡 TIP —
<script setup>안에서 선언한 변수·함수는 별도return없이template에서 그대로 쓸 수 있습니다. 옛 방식(export default { setup() {...} })보다 훨씬 간결합니다.
반응형 상태 — ref
import { ref } from 'vue';
const name = ref('민수');
console.log(name.value); // script 안에서는 .value 로 접근
name.value = '영희'; // 변경하면 화면도 자동 갱신
ref 는 값을 감싸는 반응형 상자를 만듭니다. 상자 안의 진짜 값은 .value 로 꺼내고 넣습니다. 이 값을 바꾸면 그 값을 쓰는 화면이 자동으로 다시 그려집니다.
template안에서는.value없이{{ name }}으로 바로 씁니다. Vue가 자동으로 풀어주기 때문입니다.
⚠️ 주의 —
script안에서.value를 빼먹고name = '영희'처럼 쓰면 반응성이 깨집니다. 항상name.value로 접근하세요.
디렉티브
디렉티브는 v- 로 시작하는 특수 속성으로, HTML 요소에 동작을 부여합니다.
<template>
<input v-model="text" /> <!-- 양방향 바인딩 -->
<p v-if="text">입력됨: {{ text }}</p>
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
</template>
| 디렉티브 | 역할 |
|---|---|
v-model | 폼 입력 양방향 바인딩 |
v-if / v-else | 조건부 렌더링 |
v-for | 리스트 반복 |
:속성 | 속성 바인딩 (v-bind 축약) |
@이벤트 | 이벤트 리스너 (v-on 축약) |
각 디렉티브의 자세한 사용법은 다음 강의에서 하나씩 다룹니다.
요약
- SFC는
template·script setup·style scoped한 파일로 컴포넌트를 정의한다. ref로 반응형 상태를 만들고,script에서는.value로,template에서는 그냥 이름으로 쓴다.- 디렉티브(
v-접두사)는 요소에 바인딩·조건·반복 같은 동작을 붙인다.
연습문제
- 버튼을 누를 때마다 1씩 줄어드는
count컴포넌트를 만들어 보세요. ref('')로 만든message를 input과v-model로 연결하고, 입력한 값을<p>에 그대로 보여 주세요.<style scoped>의 스타일이 다른 컴포넌트에 영향을 주지 않는 이유를 한 문장으로 설명해 보세요.
힌트 — 감소는
count.value--.v-model="message"와{{ message }}를 함께 쓰면 입력이 즉시 반영됩니다.
💡 연습문제 풀이
불러오는 중…
댓글 0
“Vue.js” 강좌에 대한 댓글입니다.