본문 바로가기
framework_library/vue

🌱 Vue.js 시작하기 - 템플릿 문법 완전정복

by 죄니안죄니 2025. 5. 1.

🌱  Vue.js 시작하기 - 템플릿 문법 완전정복

Vue 기초 시리즈 > 1️⃣ Vue 기본 개념 이해 > 3️⃣ Vue 템플릿 문법 완전정복


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 차이점 완전정복

댓글