(Vue 3) Custom v-directive 만들기
참고문서 : https://v3.ko.vuejs.org/guide/custom-directive.html
오늘은 vue 3에서 custom v-directive를 만드는 방법을 알아보겠습니다.
만들기 앞서 v-directive란 뭔지 한번 짚고 넘어가볼게요.
v-directive란?
Vue로 개발을 하다보면 v-if, v-for, v-model 같은 앞에 v 접두사를 붙인 단어들을 한번씩은 사용해보게 됩니다.
이렇게 v 접두사가 붙은것들을 v-directive라고 합니다.
v-directive를 사용하면 복잡한 기능을 단어 하나만 붙여서 해결하는것이 가능하기 때문에 매우 편리하고 강력한 기능이지요.
그런데 Vue에서 기본적으로 제공하는 v-directive의 종류는 많지 않습니다. 따라서 더 다양한 v-directive를 사용하고 싶다면 직접 만들어야합니다. 이렇게 직접 만든 v-directive를 사용자 지정 디렉티브(custom v-directive)라고 부릅니다.
목차
이번 포스팅에선 순서대로 custom directive를 만드는 두가지 방법과 디렉티브를 정의하는 두가지에 대해 알아보겠습니다.
3. 디렉티브 훅함수
4. 디렉티브 전달인자
custom v-directive 만들기
custom v-directive를 만들어 볼건데 크게 두가지 방법이 있습니다.
각각 모든 컴포넌트에서 사용할 수 있도록 전역적으로 만드는 방법과 해당 컴포넌트에서만 사용할 수 있도록 로컬로 만드는 방법입니다.
전역 custom directive
먼저 전역적으로 사용할 수 있는 custom directive를 만들어봅시다.
index.html에다 App.vue를 박아넣는 역할인 main.js 파일을 열고 아래와 같이 코드를 작성하면 됩니다.
// main.js 파일
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
// 전역 custom directive v-focus 등록
app.directive('focus', {
mounted(el) { // 바인딩 된 엘리먼트가 DOM에 마운트 될때
el.focus() // 엘리먼트에 포커스를 줍니다.
}
})
app.mount('#app');
위 코드는 v-focus라는 directive를 만들어서 모든 컴포넌트에 사용할 수 있도록 전역적으로 등록하는 코드입니다. v-focus는 바인딩 된 요소가 처음 마운트될 때 해당 요소에 포커싱을 주는 디렉티브입니다.
중점적으로 봐야하는 부분은 app.directive()입니다.
-> app.directive를 간소하게 나타내면 이렇습니다.
app.directive('directive이름', { 디렉티브 정의 객체 })
위에선 'directive이름' 부분에 'focus'를 넣었으니 만들어지는 디렉티브는 v-focus가 되겠죠.
'디렉티브 정의 객체'는 훅함수가 들어가는 곳입니다. 훅함수가 무엇인지는 조금 이따가 알아보도록 하겠습니다.
로컬 custom directive
다음으로 디렉티브가 정의된 컴포넌트 내에서만 사용할 수 있는 로컬 custom directive를 만들어봅시다.
디렉티브를 사용할 컴포넌트에다가 아래와 같이 코드를 작성하면 됩니다.
<template>
아무 컴포넌트 내용
</template>
<script>
export default {
directives: {
focus: { // directive 정의
mounted(el) {
el.focus()
}
}
}
}
</script>
로컬 디렉티브는 directives 속성을 사용하여 만듭니다.
-> directives 속성의 구조는 다음과 같습니다. 전역 디렉티브를 만들때 사용한 app.directive()와 비슷합니다.
directives: {
디렉티브이름: { 디렉티브 정의 객체 }
}
위에서 '디렉티브 정의 객체'는 훅함수가 들어가는 곳이라고 언급했었습니다.
그럼 훅함수는 뭘까요?
훅함수
디렉티브의 훅함수는 컴포넌트의 라이프사이클 훅과 비슷합니다. 디렉티브의 라이프사이클 별로 호출되는 함수라고 생각하시면 됩니다.
공식문서를 보면 훅함수의 종류는 다음과 같이 나오네요.
영어 공식문서를 보면 추가로 created 훅도 있는것 같습니다.
* Vue 3와 Vue 2에서의 훅함수는 다릅니다. 꼭 주의해주세요
(아래는 vue 2의 훅함수입니다.)
보통 beforeMount, mounted, updated, unmounted만 사용합니다. 특히 mounted를 많이 사용합니다.
위의 예제에선 v-focus를 만들 때 mounted를 사용했으니 바인딩된 요소가 부모 컴포넌트에 마운트 될 때, 훅함수 안에 있는 함수가 실행되겠네요.
추가로 훅함수는 전달인자로 4가지를 받습니다.
디렉티브 전달인자
훅함수는 인자로 (el, binding, vnode, preVnode)를 받는데, 우리는 el과 binding만 사용할거니 이 두개에 집중해주세요.
el로는 v-directive를 붙인 요소가 들어옵니다.
ex)
<input v-focus />
-> el로 input 요소가 들어옴
binding으로는 argument, modifiers, 그리고 value가 옵니다.
형태는 v-mydirective:arguement.modifiers="{ valueKey : valueValue }"입니다.
<template>
<div v-custom1:hello.background="{ color : 'red' }">
sample
</div>
</template>
<script>
export default {
name: 'App',
directives: {
custom1: {
mounted(el, binding){
el.innerText = binding.arg;
if(binding.modifiers.background){
el.style.backgroundColor = binding.value.color;
} else if(binding.modifiers.color) {
el.style.color = binding.value.color;
}
}
}
}
}
</script>
<style>
div{
width: 60px;
height: 60px;
background-color: wheat;
text-align: center;
}
</style>
위의 코드는 'custom1'이라는 디렉티브를 사용한 요소의 내용을 argument로 전해준것으로 바꾸고, modifiers에 따라 background나 color 둘 중 하나를 value로 전해준 red로 바꾸는 코드입니다.
코드를 보면, argument는 binding.arg로, modifiers는 binding.modifiers로 value는 binding.value로 받습니다.
각각을 잘 이용하면 상황에 맞게 좀 더 디테일하게 디렉티브를 조정하여 사용할 수 있습니다.
argument와 value의 경우 아래와 같이 동적(dynamic)으로 전달할 수 도 있습니다. (modifiers는 정적으로만 가능합니다)
<div id="dynamicexample">
<h2>Scroll down the page</h2>
<input type="range" min="0" max="500" v-model="pinPadding">
<p v-pin:[direction]="pinPadding">Stick me {{ pinPadding + 'px' }} from the {{ direction }} of the page</p>
</div>
const app = Vue.createApp({
data() {
return {
direction: 'right',
pinPadding: 200
}
}
})
app.directive('pin', {
mounted(el, binding) {
el.style.position = 'fixed'
const s = binding.arg || 'top'
el.style[s] = binding.value + 'px'
},
updated(el, binding) {
const s = binding.arg || 'top'
el.style[s] = binding.value + 'px'
}
})
마무리
디렉티브를 만드는 방법 2가지와(전역, 로컬) 디렉티브를 정의하는 2가지(훅함수, 전달인자)를 알아보았습니다.
커스텀 디렉티브를 사용하면 모션이나 lazy-loading, 무한스크롤 등의 기능을 매우 쉽게 만들 수 있습니다. 이때 훅함수와 전달인자를 적절히 잘 사용한다면 더욱 재활용성이 높은 디렉티브를 만들 수 있지요.
조금 어렵겠지만 꼼꼼히 공부해보시면 나중에 분명 유용하게 쓰실 수 있을겁니다.
이해가 안되는 부분이 있다면 댓글 남겨주세요 :)
* 오류 지적은 언제나 환영입니다.
'프론트엔드 > Vue' 카테고리의 다른 글
Vue2에서 clearTimeout & clearInterval 하는법 (0) | 2022.01.19 |
---|---|
(Vue 3) non-emits event 경고 (0) | 2022.01.16 |
댓글