Vue에서 디렉티브(Directive)란 v- 접두사가 붙은 특수 HTML 속성을 의미합니다.
디렉티브는 템플릿에서 요소의 동작을 제어하거나 바인딩할 때 사용되며, Vue 템플릿의 핵심 기능 중 하나입니다.
Vue의 디렉티브는 아래와 같이 4가지 구성 요소로 나뉩니다:

| 구성 요소 | 설명 | 예시 |
|---|---|---|
| name | 디렉티브 이름 (v-bind, v-on, 사용자 정의 등) | v-bind |
| argument | 디렉티브의 대상 속성 또는 이벤트 이름 | href, click, title 등 |
| modifiers | 디렉티브의 동작을 조정하는 후처리 플래그 | .prevent, .stop, .once 등 |
| value | 디렉티브에 전달되는 자바스크립트 표현식 | "url", someValue |
Vue에서는 자주 사용되는 디렉티브들에 대해 축약 문법도 제공하며, 공식 문서에서 더 많은 디렉티브를 확인할 수 있습니다.
앞서 디렉티브의 구조와 기본 개념을 살펴보았으니, 이번에는 자주 사용되는 핵심 디렉티브들을 하나씩 정리해보겠습니다.
v-bind는 HTML 요소의 속성(Attribute)에 JavaScript 데이터를 바인딩할 때 사용합니다.
<img v-bind:src="imageUrl" />
위 예시는 img 태그의 src 속성에 imageUrl 이라는 데이터를 바인딩한 것입니다.
v-bind는 다음과 같이 축약형으로 사용할 수도 있습니다.
<img :src="imageUrl" />
주의할 점은 : 을 잊으면 안된다는 것입니다.
v-on은 DOM 이벤트를 Vue 메서드에 연결할 때 사용합니다.
<button v-on:click="submitForm">Submit</button>
위 예시는 button 태그의 click 속성 이벤트가 일어날 때,
submitForm 이라는 자바스크립트 함수가 실행되게끔 연결해 놓은 것입니다.
v-on도 다음과 같이 축약형으로 사용할 수 있습니다.
<button @click="submitForm">Submit</button>
주의할 점은, v-on: 까지 @으로 대체된다는 것입니다. ( 콜론을 사용할 필요 없음. )
v-bind가 JavaScript → HTML 방향의 데이터 바인딩을,
v-on이 HTML → JavaScript 방향의 이벤트 처리를 담당했다면,
v-model은 이 두 역할을 한 번에 처리하는 양방향 바인딩 도구입니다.
v-model은 단순한 입력 동기화를 넘어서 다양한 입력 요소와 상황에 따라 매우 유연하게 동작합니다.
이에 대한 자세한 내용은 다음 포스트에서 깊이 있게 다루고 있습니다.
v-if는 조건에 따라 DOM 요소를 생성하거나 제거합니다.
<template>
<div>
<p v-if="isLogin">Welcome</p>
<p v-else-if="isGuest">Hello, Guest</p>
<p v-else>Please log in</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const isLogin = ref(false)
const isGuest = ref(true)
</script>
조건이 false일 경우, 해당 요소는 아예 DOM에 존재하지 않습니다.

조건에 따라 DOM 생성되는 것을 볼 수 있습니다.
v-show는 항상 렌더링은 하되, display: none으로 숨깁니다.
<template>
<div>
<button @click="isVisible = !isVisible">
토글하기
</button>
<p v-show="isVisible">안녕하세요!</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const isVisible = ref(false)
</script>

요소는 이미 렌더링되어 있으나, style 속성에 따라 화면에 보일지 여부가 결정됩니다.
v-if는 조건이true일 때만 DOM이 존재하고,
v-show는 항상 존재하지만display:none으로 숨긴다는 명확한 차이가 있습니다.
따라서 사용 시점에 따라 적절히 사용하는 것이 좋습니다.
v-for는 배열/객체/숫자 등을 반복 렌더링할 때 사용합니다.
<template>
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue'
const items = ref([
{ id: 1, name: '사과' },
{ id: 2, name: '바나나' },
{ id: 3, name: '딸기' },
])
</script>

Vue에서는 v-for를 쓸 때 :key를 꼭 넣어주는 게 좋습니다.
이는 Vue가 DOM을 효율적으로 업데이트하기 위해 각 항목을 고유하게 식별할 수 있도록 돕습니다.
주의사항
v-for와 v-if는 같은 요소에 동시에 사용할 수 없다.
<template>
<ul>
<li v-for="item in items" v-if="item.show" :key="item.id">
{{ item.name }}
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue'
const items = ref([
{ id: 1, name: '사과', show: true },
{ id: 2, name: '바나나', show: false },
{ id: 3, name: '딸기', show: true },
])
</script>
실제로 이 코드를 실행해보면, show: true인 항목만 보여질 것 같지만, 화면에는 아무것도 렌더링되지 않습니다.
해결방법
computed로 미리 필터링한다.<template>
<ul>
<li v-for="item in visibleItems" :key="item.id">
{{ item.name }}
</li>
</ul>
</template>
<script setup>
import { ref, computed } from 'vue'
const items = ref([
{ id: 1, name: '사과', show: true },
{ id: 2, name: '바나나', show: false },
{ id: 3, name: '딸기', show: true },
])
const visibleItems = computed(() =>
items.value.filter(item => item.show)
)
</script>
v-if 조건을 걸기보다는, computed 속성에서 show가 true인 항목만 미리 필터링해 v-for에 전달하는 방식입니다.
이렇게 하면 렌더링 시 조건 검사 없이 깔끔하게 필요한 항목만 출력할 수 있어 성능과 가독성 모두 좋아집니다.
template 태그로 분리한다.<template>
<ul>
<template v-for="item in items" :key="item.id">
<li v-if="item.show">
{{ item.name }}
</li>
</template>
</ul>
</template>
<script setup>
import { ref } from 'vue'
const items = ref([
{ id: 1, name: '사과', show: true },
{ id: 2, name: '바나나', show: false },
{ id: 3, name: '딸기', show: true },
])
</script>
Vue에서는 v-for와 v-if를 같은 요소에 동시에 사용하는 대신, template 태그를 활용해 조건을 분리할 수 있습니다.
template은 실제 DOM 요소를 만들지 않기 때문에, 반복과 조건을 안전하게 조합할 수 있습니다.
v-text는 텍스트 콘텐츠를 출력할 때 사용하는 디렉티브입니다.
{{ ... }} 머스태시 문법과 역할은 같지만, HTML이 아닌 순수 텍스트만 삽입됩니다.
<p v-text="message"></p>
<!-- 위 코드는 아래와 동일한 결과 -->
<p>{{ message }}</p>
머스태시 문법은 하나의 표현만 가능하지만
v-text는 조건부 렌더링과 함께 사용할 수 있어 유연성이 있습니다.
예를 들어 다음처럼 쓸 수 있습니다.
<p v-if="show" v-text="message"></p>
주의사항
v-text는 텍스트만 렌더링합니다.
HTML 태그를 문자열로 포함하더라도 그대로 문자열로 출력됩니다.
만약 HTML을 실제로 렌더링하려면 v-html을 사용해야 합니다.
지금까지 Vue의 주요 디렉티브들을 살펴보았습니다.
다음 글에서는 v-model에 대해 집중적으로 다뤄보겠습니다.