서론
HTML 태그안에 v-model, v-for 같이 v로 시작하는 속성(attribute)을 디렉티브라고 합니다. 더 자세히는 v-model 같이 개발자가 따로 정의하지 않아도 vue에서 바로 쓸 수 있는 것들을 빌드인 디렉티브라고 하는데, 여기서는 개발자가 별도로 디렉티브를 정의해보고 사용하는 방법에 대해 알아보겠습니다.
목차
- 커스텀 디렉티브 만들기
- 커스텀 디렉티브 예시(입력값 제한하기)
- 업무효율을 높이는 방법
커스텀 디렉티브 만들기
1. 컴포넌트에 정의하기
(1) 컴포넌트 directives코드 작성
custom directive를 사용하려는 컴포넌트의 script 태그에 directive 키를 추가하고, 그 속에 오브젝트 형식으로 개발자가 사용하려는 directive를 정의합니다.
아래 예시는, 페이지가 생성되면 자동으로 입력창 커서가 켜지는, focus기능을 담은 directive 예시입니다.
export default {
components: {},
// directive 정의하기
directives: {
focus: {
mounted(el, binding) {
// console.log(el) // custom-directive가 있는 element를 지칭
el.focus()
}
}
}
주의할 점으로, 디렉티브를 정의할 때 네이밍은 접두어 v를 제외하고 입력합니다.
또한, directive가 어느 단계에서 작동을 할지 지정해줘야 됨으로, mounted를 사용했으며, mounted안에 2개의 파라미터가 있는데 첫번째는, directive가 쓰인 요소를 가르키고, 두번째는 directive에 바인딩한 데이터를 가르킵니다.(바인딩한 데이터값이 없다면 생략해도 됨.)
- 추가설명
vue에서는 LifecycleHook 이란게 있는 데, vue가 각 컴포넌트를 실행할 때 실행되는 과정을 단계별로 나타낸 것입니다. 여기서 mounted는 HTML의 모든 요소가 생성이되면 실행하라는 의미를 갖고 있습니다.
즉, 개발자가 새롭게 정의한 v-focus라는 directive를 사용하게 되면, 해당 컴포넌트의 HTML요소들이 모두 생성된 이후 mounted 내부코드 인 el.focus()가 실행되게 됩니다.
(2) HTML 요소에 directive 사용하기
위에서 작성한 directive를 아래 코드와 같이 적용하면, 페이지를 켰을 때, 입력창의 커서가 자동으로 켜지는 효과가 생깁니다.
// input태그에 v-focus 추가
<div>
<label for="email" class="form-label">이메일 주소</label>
<input type="email" name="" id="email" class="form-control" v-focus />
</div>
2. 커스텀 디렉티브 예시
그럼 위에서 배운 내용으로, 실제 개발에 활용할만한 디렉티브를 만들어 보았습니다.
아래는 사용자로부터 소문자만 받는 디렉티브, 대문자만 받는 디렉티브, 숫자만 받는 디렉티브, 한글만 받는 디렉티브에 대한 코드 예시입니다.
directives: {
// 소문자만 입력받기
lowercase: {
mounted(el) {
el.addEventListener('input', (event) => {
event.target.value = event.target.value.toLowerCase()
})
}
},
// 대문자만 입력받기
uppercase: {
mounted(el) {
el.addEventListener('input', (event) => {
event.target.value = event.target.value.toUpperCase()
})
}
},
// 숫자만 입력받기, 정규식 활용
number: {
mounted(el) {
el.addEventListener('input', (event) => {
console.log(event.target.value)
event.target.value = event.target.value.replace(/\D/g, '')
})
}
},
// 한글만 입력받기, 정규식 활용
korean: {
mounted(el) {
el.addEventListener('input', (event) => {
console.log(event.target.value)
event.target.value = event.target.value.replace(
/[^ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g,
''
)
})
}
}
위에서 'input' 이벤트를 활용했는데, input이벤트는 사용자가 입력한 값을 요소의 value로 입력은 되나 아직 화면에 표현은 하지 않은 상태 입니다. 즉, value에 입력도 되고 화면에 표현도 되고 있는 keyup 이벤트의 바로 전단계 이벤트라고 보면 되는데, 이를 활용해서 화면에 출력되기 전에 그 입력된 값들을 개발자의 목적에 맞는 메소드를 적용하여 출력할 수 있습니다.
예를 들어, 숫자만 입력받아야 되는 경우 숫자 외의 값들은 화면에 출력되기 전에 replace메소드를 적용해서 모두 없는 값으로 만들면, 입력제한을 할 수 있는 거죠.
3. 업무효율을 높이는 방법
만약, 위에서 구현한 direcitve 기능을 다른 페이지에서도 활용해야 될 때, 굳이 똑같은 코드 내용을 또 작성할 필요가 없습니다.
바로, main.js 파일에 정의를 하면 다른 컴포넌트에서도 해당 directive를 바로 사용할 수 있기 때문이죠.
기본적으로 vue 프로젝트를 생성하면 main.js파일에 아래와 같이 코드가 되어있을 텐데
createApp(App).use(store).use(router).mount('#app')
아래와 같이 코드를 좀 세분화 시켜주고(디렉티브 적용을 위해)
const app = createApp(App)
app.use(store)
app.use(router)
app.mount('#app')
아래와 같이 custom directive를 main.js에 직접 정의해줍니다. (directives를 추가할 때 순서는 상관없고, app.mount 이전이기만 하면 됨)
const app = createApp(App)
app.use(store)
app.use(router)
// custom directive 추가
app.directive('lowercase', {
mounted(el) {
el.addEventListener('input', (event) => {
event.target.value = event.target.value.toLowerCase()
})
}
})
app.directive('uppercase', {
mounted(el) {
el.addEventListener('input', (event) => {
event.target.value = event.target.value.toUpperCase()
})
}
})
app.directive('number', {
mounted(el) {
el.addEventListener('input', (event) => {
console.log(event.target.value)
event.target.value = event.target.value.replace(/\D/g, '')
})
}
})
app.directive('korean', {
mounted(el) {
el.addEventListener('input', (event) => {
console.log(event.target.value)
event.target.value = event.target.value.replace(
/[^ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g,
''
)
})
}
})
app.mount('#app')
위 작업을 통해서 어느 컴포넌트에서든 쉽게 접근할 수 있는 custom directive를 정의하였습니다.
결론
커스텀 디렉티브를 정의하는 방법에 대해 알아보았습니다. 반복적이고 복잡할 수 있는 코드작업을 잘 정리해놓으면, v로 시작하는 디렉티브 한 단어만으로 기능을 손쉽게 재활용할 수 있습니다. 해당 기능을 잘 활용하여 중복된 코드를 제거하고 업무효율을 높이는 데 활용하시면 좋을 것 같습니다.
'코딩기록 > Vue.js' 카테고리의 다른 글
[vue]라우팅 방식 이해하기 (1) | 2023.01.15 |
---|