vue.js directive란? vue directive란? custom directive

Vue.js Directive란?
Vue.js를 사용하여 템플릿에 자바스크립트를 추가하는 방법을 제공하는 특별한 마크업입니다.
HTML 태그에 v-접두사가 있는 속성 입니다.
예를들어, 아래와 같은 vue 코드에서
v-if, v-for 등이 directive라고 지칭되는 것들 입니다.
<template>
<p v-if="seen">Now you see me</p>
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
<template>
참고로, directive, 한글 발음으로 디렉티브는 지시자라는 뜻을 가집니다.
Directive의 종류
vue에서 대표적인 directive는 다음과 같은 것들이 있습니다.
자주 사용하시는것이니 익혀두시는게 좋습니다.
- v-model: 양방향 데이터 바인딩을 생성
- v-show: 조건에 따라 요소를 표시
- v-if: 조건에 따라 요소를 렌더링
- v-for: 배열 또는 객체의 요소를 기준으로 요소를 반복적으로 렌더링
- v-on: 이벤트 리스너를 추가
- v-bind: 속성이나 props를 바인딩
Directive 사용법 (예시코드)
예시코드를 살펴보겠습니다.
아래와 같은 코드를 작성해보았습니다.
<template>
<div id="app">
<!-- v-model directive -->
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
<!-- v-if directive -->
<p v-if="seen">Now you see me</p>
<!-- v-for directive -->
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
<!-- v-on directive -->
<button v-on:click="reverseMessage">Reverse Message</button>
<!-- v-bind directive -->
<a v-bind:href="url">This is a link</a>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello Vue!',
seen: false,
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue' },
{ text: 'Build something awesome' }
],
url: '<https://vuejs.org/>'
}
},
methods: {
reverseMessage() {
this.message = this.message.split('').reverse().join('')
}
}
}
</script>
아래 코드는 message 변수를 양방향 바인딩 한다는 의미로,
해당 칸의 input값을 바꾸면 그 아래에 있는
{{message}} 부분이 바뀌어보이게 됩니다.
<input v-model="message" placeholder="edit me">
아래 코드는 seen이라는 변수가 true면 보이고,
false면 안보이게 한다는 내용입니다.
변수값을 false 로 설정했으므로, 해당 요소는 보이지 않을것입니다.
<p v-if="seen">Now you see me</p>
아래코드는 todos 에 3개의 값이 있으므로 3줄이 보여질 것입니다.
<li v-for="todo in todos">
{{ todo.text }}
</li>
아래코드는 눌렀을때 reverseMessage함수가 실행됩니다.
<button v-on:click="reverseMessage">Reverse Message</button>
아래 코드는 href attribute 값을 url 변수로 바꾼다는 내용입니다.
<a v-bind:href="url">This is a link</a>
최종적으로, 이 코드를 실행하면 아래와 같이 보여집니다.

custom directive
개발자가 새로운 directive를 만들 수도 있습니다. (사용자 정의 directive)
원하는 기능이 직접적인 DOM 조작을 통해서만 구현될 수 있을 때 사용할 수 있습니다.
vue3에서는 custom directive를 추가하는 방법을 3가지 제공합니다.
첫번째 방식으로, main.js 에서 아래와 같이 전역적으로 v-bold라는 디렉티브를 추가할 수 있습니다.
예제코드는 이 디렉티브가 선언되어 있으면, is-bold라는 클래스를 추가하겠다는 단순한 코드입니다.
const app = createApp({})
// 모든 컴포넌트에서 v-bold를 사용할 수 있도록 합니다.
app.directive('bold', {
mounted: (el) => {
el.classList.add('is-bold')
}
})
두번째 방식으로 <script setup>
을 사용하는 vue파일에서 사용할수 있는 방식입니다.
<script setup>
// 템플릿에서 v-bold로 활성화 가능
const vHighlight = {
mounted: (el) => {
el.classList.add('is-bold')
}
}
</script>
마지막으로 <script setup>
을 사용하지 않는 vue파일에서 사용할 수 있는 방식입니다.
export default {
setup() {
/*...*/
},
directives: {
// 템플릿에서 v-highlight로 활성화 가능
bold: {
/* ... */
}
}
}
template에서는 이 custom directive를 사용하려면,
아래와 같이 선언하여 사용해주시면 됩니다.
<template>
<p v-bold>This sentence is important!</p>
</template>
directive 사용시 주의사항
directive 사용시 몇가지 주의사항이 있습니다.
1) 가능한 디렉티브 동시에 사용하지 않기
Vue에서 두 지시문을 동일한 노드에 사용하는 것은 권장되지 않습니다.
예를들어, v-for가 v-if보다 높은 우선 순위를 가지므로 예상치 못한 동작을 유발할 수 있습니다.
2) v-for와 고유 키
v-for 디렉티브를 사용하여 배열을 반복할 때는 항상 고유한 'key' 속성을 제공해야 합니다.
이는 Vue가 각 노드의 ID를 추적하고 효율적으로 재사용할 수 있도록 합니다.
예를 들어, v-for를 사용할때는 아래와 같이 key 속성을 넣어 코드 작성할 수 있도록 합니다.
<div v-for="(person, index) in people" :key="index">
{{ index }} 이름: {{ person.name }} 나이: {{ person.age }}
</div>
총평
찾아보니 vue의 directive는 angular에서 영감을 받았다고 하더군요.
근데 그 전에, 다른 프로그래밍 언어에서도 영향 받지 않았을까 싶습니다.
개인적으로는 java진여의 jstl과 mybatis가 생각이 났습니다.
xml에서 사용하고, if, for 등을 쓸 수 있는게 비슷하다는 느낌이 많이 들었습니다.
그 외에도 많은 템플릿 엔진들에서도 비슷하게 사용하던것으로 기억하는데,
참으로 편리하게 잘 만들었다라는 생각이 드네요.
HTML5에서 기본적으로 if나 for 등을 지원했었으면 좀 더 편하게 코딩할 수 있지 않을까 싶다는 생각이 들었습니다.
'자바스크립트 - Javascript' 카테고리의 다른 글
react에서 useState로 배열 상태값 변경하기, spread syntax (0) | 2024.10.12 |
---|---|
vue3 빌드하지않고 사용하기 (0) | 2024.09.20 |
vue3 lifecycle hook, vue3 라이프사이클 순서, vue3 onMounted/unmounted/beforecreate, vue3 라이프사이클 예제코드 (3) | 2024.09.16 |
vue3 router 사용법, vue router params, vue router push, vue router history, vue dynamic route (1) | 2024.09.04 |
vue3 watch 사용법, vue3 watch 여러개, vue3 watchEffect 사용법 (0) | 2024.08.20 |
댓글