🌱 Vue.js 시작하기 - 템플릿 문법 완전정복
Vue 기초 시리즈 > 1️⃣ Vue 기본 개념 이해 > 3️⃣ Vue 템플릿 문법 완전정복
- 1. Vue 템플릿 문법이란?
- 2. Mustache 구문과 데이터 바인딩
- 3. 주요 디렉티브 정리 (v-bind, v-model 등)
- 4. 축약형 문법
- 5. 템플릿 표현식 제약
- 6. 실전 팁 & 디렉티브 선택 기준
- 🔚 마무리 & 다음 글 안내
1. Vue 템플릿 문법이란?
Vue 템플릿은 HTML 기반의 마크업에 Vue 디렉티브와 바인딩 문법을 더해 동적 UI를 구성하는 핵심입니다. . 대부분의 Vue 컴포넌트는 템플릿 안에 데이터 바인딩과 디렉티브를 활용하여 로직 없이도 뷰와 데이터를 연결합니다. (기존에는 태그요소를 직접 선택해서 변수에 담아서 값을 변경하는 코드를 작성해야 했던 것을 자동화 한 것)
핵심: 데이터 변경 시 DOM이 자동으로 갱신됩니다. (반응형 시스템)
2. Mustache 구문과 데이터 바인딩
{{ }}
중괄호 문법은 데이터를 HTML에 출력하는 가장 기본적인 방법입니다. JavaScript 표현식을 그대로 출력할 수 있습니다.
//html
<p>{{ message }}</p>
<p>{{ count + 1 }}</p>
<p>{{ user.name.toUpperCase() }}</p>
<p>{{ isActive ? '활성' : '비활성' }}</p>
//js
data() {
return { message: '안녕 Vue' }
}
- 해당 표현식은 DOM에 렌더링될 때 자동으로 갱신됩니다. 즉, message가 "안녕 Vue"에서 "반가워 Vue"로 변경되면 DOM에 있는 <p> 태그도 자동으로 변경됩니다. ("반응형(Reactive) 렌더링")
- 단방향 바인딩 (데이터 → 뷰만 반영)
주의사항: 템플릿 안에서는 if/for 같은 문(statement)은 사용할 수 없습니다. 오직 표현식(expression)만 허용됩니다.
<p>{{ if (isActive) { return '활성' } }}</p> <!-- ❌ 불가능. 오류 발생 -->
3. 주요 디렉티브 정리
✅ v-bind: 속성에 JS 데이터 연결
HTML 속성에 동적으로 값을 바인딩합니다. 즉, Vue에서는 단순히 텍스트만이 아니라 HTML 속성(src, href, id, class 등)에도 변수를 연결할 수 있습니다. (렌더링 후 값이 들어감)
//html
<img v-bind:src="imageUrl" />
//js
data() {
return {
imageUrl: '/images/photo.jpg'
};
}
//렌더링 후 html
<img src="/images/photo.jpg" />
축약형: :src="imageUrl"
Tip: 조건부 클래스나 스타일도 객체 형태로 사용 가능합니다.
<div :class="{ active: isActive }">버튼</div>
✅ v-model: 양방향 데이터 바인딩
양방향 데이터 바인딩을 위한 디렉티브입니다. 사용자 입력이 즉시 반영됩니다.
<input v-model="username" />
내부적으로 v-bind:value와 v-on:input을 동시에 처리합니다.
주의: v-model은 폼 요소에만 사용하세요. 커스텀 컴포넌트에선 modelValue + update:modelValue를 지원해야 합니다.
주의: v-bind
는 단방향 (props나 속성 값 전달) / v-model
은 양방향 (폼 요소와 데이터 상호 연결)
✅ v-if / v-else-if / v-else: 조건부 렌더링
조건부 렌더링을 할 수 있습니다.
<div v-if="isAdmin">관리자 메뉴</div>
<div v-else-if="isUser">사용자 메뉴</div>
<div v-else>게스트 메뉴</div>
주의: v-if와 v-for를 같은 요소에 쓰면 예상치 못한 버그가 생길 수 있으므로, 별도 <template> 태그로 감싸세요.
✅ v-for: 반복 렌더링
배열/객체의 반복 렌더링에 사용합니다.
<!-- 배열 반복 -->
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
<!-- 객체 반복 -->
<li v-for="(val, key) in user" :key="key">{{ key }}: {{ val }}</li>
<li v-for="(item, index) in items" :key="index"> {{ item }}</li>
- 배열: 순서대로 반복
- 객체: key-value 쌍을 반복 (성능 저하 주의)
주의: 반드시 :key 속성을 넣어 성능과 안정성을 확보하세요.
✔ 차이점:
항목 | 배열 | 객체 |
순서 있음 | 예 (0번, 1번, 2번...) | 없음 (key 순서 보장 X) |
v-for 구조 | (item, index) in list | (val, key) in object |
key 설정 필수 | 네 (:key="item.id" 권장) | 네 (:key="key" 설정해야 안전) |
실무에서는 배열을 주로 반복합니다. 객체는 key-value 형태를 표현할 때만 씁니다.
✅ v-on: 이벤트 바인딩
이벤트 핸들러를 바인딩합니다.
//html
<button v-on:click="submit">제출</button>
//js
methods: {
handleClick(event) {
console.log(event); // 자동으로 넘겨진 이벤트 객체
}
}
팁: $event는 이벤트 객체를 넘기고 싶을 때만 사용하면 됩니다. 👉 기본적으로 이벤트 객체는 자동으로 넘겨집니다. 하지만 명시적으로 쓰는 경우:
- 여러 인자를 함께 넘기고 싶을 때
<button @click="handleClick(item, $event)">선택</button>
- event.preventDefault()를 직접 호출해야 할 때
- 키보드 이벤트나 마우스 위치 등 이벤트 상세 정보가 필요할 때
✅ 결론: 대부분의 경우 명시적으로 안 넘겨도 되지만, 커스텀 처리 시에는 꼭 필요합니다.
축약형: @click="submit"
이벤트 수식어: .prevent
,.stop
,.once
등으로 이벤트 동작 제어 가능
<form @submit.prevent="onSubmit">
4. 기타 템플릿 디렉티브 소개
✅ v-text
html
복사편집
<p v-text="message"></p>
→ {{ message }}와 동일하지만, HTML escape가 자동 적용됨.
✅ v-html
html
복사편집
<p v-html="rawHtml"></p>
→ HTML 태그를 실제로 렌더링.
⚠ 주의: XSS 공격 가능성 있음 → 외부 입력값 사용 금지
✅ v-pre
html
복사편집
<span v-pre>{{ rawMustache }}</span>
→ 해당 영역은 Vue가 파싱하지 않고 그대로 출력합니다. (디버깅용/성능최적화)
✅ v-cloak
- 컴포넌트 로딩 전까지 <div v-cloak>을 숨길 수 있게 해주는 유틸용
css
복사편집
[v-cloak] { display: none; }
5. 디렉티브 축약형 정리
표현 | 설명 | |
---|---|---|
:prop |
v-bind:prop 축약 |
|
@event |
v-on:event 축약 |
6. 템플릿 표현식 제약
- 템플릿 안에서는 표현식만 허용됩니다.
if/else, for문, 변수 선언
등은 사용 불가- 삼항연산자는 표현식이라 사용 가능
<p>{{ isAdmin ? '관리자' : '일반 사용자' }}</p>
7. 실전 팁 & 디렉티브 선택 기준
v-if
는 조건이 자주 바뀌지 않는 경우에만 사용 (DOM 제거)v-show
는 토글이 자주 필요한 UI에 적합 (CSS로 숨김 처리)v-model
은 입력 요소만, 그 외는v-bind
로 대체- v-if와 v-for는 함께 쓰지 말기: 별도 <template>로 감싸 분리하는 것이 안전합니다.
- :key는 꼭 지정하기: 특히 v-for 안에서 컴포넌트 반복 시 필수입니다.
- 복잡한 계산은 템플릿이 아닌 computed에서 처리하기: 템플릿은 가독성 좋게 유지하세요.
- v-model은 폼 요소에만 사용: 커스텀 컴포넌트에서는 이벤트 핸들링 로직을 직접 구현해야 합니다.
📌 v-if vs v-show
구분 | v-if | v-show |
---|---|---|
렌더링 | DOM 자체 생성/제거 | CSS로 숨김 처리 |
성능 | 비효율적 (자주 바뀔 경우) | 빠름 (자주 토글 시) |
???. v-show vs v-if — v-if가 선호되는 경우는?
비교 항목 | v-if | v-show |
동작 방식 | 조건에 따라 DOM 자체를 만들고 제거 | DOM은 항상 존재, display:none으로 숨김 |
초기 렌더링 비용 | 높음 (조건이 true여야 렌더링) | 낮음 |
토글 빈도 | 낮을 때 적합 | 자주 토글될 때 적합 |
조건 변경 속도 | 느림 (DOM 새로 생성) | 빠름 (스타일만 바꿈) |
✔ v-if가 선호되는 경우:
- 렌더링 자체가 무거운 경우 (예: 무거운 컴포넌트, 리스트)
- 처음부터 보이지 않아야 하는 경우 (조건 충족 시에만 등장)
✔ v-show가 선호되는 경우:
- 자주 보였다 숨겨야 하는 토글 영역 (예: 탭, 드롭다운)
🔚 마무리 & 다음 글 안내
이제 Vue 템플릿 문법을 자유자재로 쓸 수 있게 되었어요!
다음 글에서는 반응형 데이터와 reactive vs ref의 차이를 중심으로 Vue의 핵심 개념을 정리합니다.
👉 다음 글: 반응형 데이터와 reactive, ref 차이점 완전정복
'framework_library > vue' 카테고리의 다른 글
🌿 Vue.js 컴포넌트 선언과 등록 방식 (전역, 지역) (0) | 2025.05.01 |
---|---|
🌱 Vue.js 반응형 데이터 이해하기 - reactive와 ref의 차이점 완전정복 (1) | 2025.05.01 |
🌱Vue.js 시작하기 - 프로젝트 생성 (Vite vs Vue CLI) (0) | 2025.05.01 |
🌱 CDN으로 간단히 Vue 앱 만들어보기 (0) | 2025.05.01 |
📚Vue.js란 무엇인가 – 점진적 프레임워크로 시작하는 프론트엔드 개발 | MMVM패턴 (0) | 2025.04.08 |
댓글