
CDN 으로 Vue를 불러와서 Composition API 중심으로 쓰는 기본 문법을 정리한 글이다.
(앱 생성 → 상태 관리 → 템플릿 → v-if / v-for → v-model → watch → 라이프사이클 순서)
createAppVue 앱은 createApp() 호출로 시작한다.
const app = createApp({
setup() {
// 반응형 상태 정의, 함수 정의
}
});
setup() 안에서 ref, reactive, computed, watch 등을 사용한다.
mount실제 DOM 요소와 연결해야 화면에 렌더링된다.
<div id="app"></div>
<script>
app.mount('#app');
</script>
mount 호출 전까지는 화면에 아무것도 그려지지 않는다ref단일 값을 반응형으로 만들 때 사용한다.
(숫자, 문자열, boolean, null, 배열 등)
const count = ref(0);
count.value++; // JS 코드에서는 .value 로 접근
특징
{{ count }} 처럼 .value 없이 바로 사용count.value 로 읽고 쓴다reactive객체 전체를 반응형으로 만든다.
const user = reactive({
name: '홍길동',
age: 20
});
user.age++; // .value 없이 바로 속성 접근
ref vs reactive 비교| 구분 | ref | reactive |
|---|---|---|
| 상태 종류 | 단일 값 | 객체 전체 |
| 접근 방식 | .value 로 접근 | 속성에 바로 접근 |
| 배열/객체 | 저장 가능하지만 .value 필요 | 본질이 객체라 더 자연스러움 |
refreactive{{ }}Mustache 문법으로 값을 출력한다.
<p>{{ message }}</p>
computed – 파생 데이터 계산computed 가 필요한가템플릿 안에서 직접 계산식을 쓰면
→ 계산 결과를 파생 상태(derived state) 로 관리할 필요가 있다.
computed 기본 사용const price = ref(1000);
const quantity = ref(2);
const total = computed(() => price.value * quantity.value);
price, quantity)이 바뀔 때만 다시 계산예시 – 문자열 길이
const message = ref('hello');
const messageLength = computed(() => message.value.length);
Vue 템플릿은 HTML 을 확장한 문법으로, 상태 기반 렌더링을 쉽게 해 준다.
v-text요소의 textContent 에 값을 채운다.
<p v-text="message"></p>
v-html (주의)HTML 문자열을 그대로 렌더링한다.
<div v-html="rawHtml"></div>
v-bind / :DOM 속성을 반응형 데이터에 연결한다.
<img :src="imgUrl" />
<div :id="dynamicId"></div>
<input :disabled="isDisabled" />
: 를 사용:class조건에 따라 클래스를 동적으로 적용할 수 있다.
<div :class="{ active: isActive }"></div>
isActive 가 true 이면 active 클래스 추가<div :class="classObject"></div>
const classObject = reactive({
active: true,
error: false
});
<div :class="['box', dynamicClass]"></div>
v-on / @<button @click="increase">증가</button>
주요 수식어
| 수식어 | 의미 |
|---|---|
.prevent | 기본 동작 방지 |
.stop | 이벤트 전파 중단 |
.once | 한 번만 실행 |
.enter | Enter 키일 때만 실행 |
실무에서 가장 자주 쓰는 부분 중 하나다.
v-show – CSS 로 토글<h1 v-show="visible">Hello</h1>
display: none / block 만 변경v-if – DOM 자체 제어<h1 v-if="isOk">OK</h1>
<h1 v-else>No</h1>
<template> + v-if불필요한 wrapper div 를 만들고 싶지 않을 때 사용.
<template v-if="show">
<h1>A</h1>
<p>B</p>
</template>
<template> 태그는 남지 않는다v-for – 반복 렌더링<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
<li v-for="(value, key, index) in obj" :key="key">
{{ index }} - {{ key }} : {{ value }}
</li>
<li v-for="n in 10" :key="n">
{{ n }}
</li>
:key 의 역할Vue 가 각 반복 요소를 어떻게 구분할지 알려주는 식별자
key 가 없으면
key 를 지정하면
실무에서는 v-for 를 쓰면 거의 항상 :key 를 같이 쓴다고 보면 된다.
v-model – 양방향 바인딩<input v-model="text" />
text 갱신text 값 변경 → input 값 반영폼 다룰 때 거의 기본으로 쓰게 되는 문법이다.
.lazy입력 중에는 반영하지 않고 blur 시점에 반영
<input v-model.lazy="name" />
.number입력 값을 숫자로 변환 시도 (실패하면 문자열 유지)
<input v-model.number="age" />
.trim앞뒤 공백 제거 후 바인딩
<input v-model.trim="text" />
select<select v-model="selectedFruit">
<option value="apple">apple</option>
<option value="banana">banana</option>
</select>
selectedFruit 에 선택한 value 가 들어간다다중 선택
<select v-model="multi" multiple>
<option value="apple">apple</option>
<option value="banana">banana</option>
</select>
multi 는 배열이 된다checkbox체크된 값들이 배열에 쌓인다.
<input type="checkbox" value="apple" v-model="fruits" />
<input type="checkbox" value="banana" v-model="fruits" />
fruits ⇒ ['apple', 'banana'] 같은 형태radio같은 v-model 을 공유하면 단일 선택
<input type="radio" value="male" v-model="gender" />
<input type="radio" value="female" v-model="gender" />
gender ⇒ 'male' 또는 'female'watch – 변화 감시watch(target, (newVal, oldVal) => {
// target 값이 바뀔 때마다 실행
});
대표적인 사용처
watch([x, y], ([nx, ny], [ox, oy]) => {
// x, y 둘 중 하나라도 바뀌면 실행
});
watch(
() => x.value + y.value,
(newSum, oldSum) => {
// x 또는 y 가 바뀌어 합이 변하면 실행
}
);
| 옵션 | 설명 |
|---|---|
immediate | 등록 직후 한 번 즉시 실행 |
once | 한 번 실행 후 자동 해제 |
deep | 객체 내부 중첩 속성까지 감시 |
flush | 콜백 실행 타이밍 제어 (post, sync 등) |
watchEffect – 의존성 자동 추적watchEffect(() => {
console.log(count.value);
});
특징
사용 예
nextTick & 라이프사이클nextTickVue 는 상태가 바뀌면 바로 DOM 을 바꾸지 않고,
한 틱 뒤에 한꺼번에 DOM 업데이트를 수행한다.
그래서 상태 변경 직후에 DOM 을 읽으면 값이 맞지 않을 수 있다.
message.value = 'update';
await nextTick(); // DOM 업데이트 완료 시점까지 대기
console.log('DOM 업데이트 이후에 실행');
사용 상황
focus() 처럼 실제 DOM 이 있어야 하는 동작Vue 컴포넌트의 주요 라이프사이클 훅은 다음 순서로 호출된다.
onBeforeMountonMountedonBeforeUpdateonUpdatedonBeforeUnmountonUnmountedonBeforeMountonMountedonBeforeUpdateonUpdatedonBeforeUnmountonUnmounted이 글에서 다룬 내용 정리
createApp → mountref, reactive, computed{{ }}, v-text, v-html, v-bind, :class, @eventv-show, v-if, <template v-if>, v-for + :keyv-model (+ .lazy, .number, .trim)watch, watchEffectnextTick, 라이프사이클 훅이 정도만 정확히 이해해도 Vue 3 Composition API 로 웬만한 화면은 충분히 만들 수 있다. 이후에는 라우터, 상태 관리, 컴포넌트 설계 패턴 등을 이어서 확장하면 된다.