뭔가를 배우는 최고의 방법은 직접 만들어 보는 것입니다.
Vue.js의 Directive를 직접 만들며 배워봅니다.
원문 : https://learnvue.co/tutorials/vue-custom-directives
- 사용자 지정 지시문이란
- Vue 지시자의 다양한 이벤트 훅
- 사용자 지정 지시문을 만드는 방법
Custom Directive란?
커스텀 디렉티브는 프로젝트를 당신의 필요에 맞게 만드는 방법입니다.
Vue 플러그인을 사용하는 경우 커스텀 디렉티브를 꽤 자주 사용한다는 것을 알 수 있습니다.
예를 들어, v-lazy plugin에서 v-lazy 지시문을 사용하여 이미지 로딩을 보다 효과적으로 만드는 커스터마이징 기능을 추가합니다.
DOM을 직접 편집하고 싶기 때문에 디렉티브를 사용하는 것이 가장 좋은 경우입니다.
컴포넌트 옵션이 추상화 및 코드 재사용에 유용하지만
사용자 지정 지시문은 여전히 DOM 요소를 직접 조작하는 가장 좋은 방법 중 하나입니다.
Directive에는 훅이 있습니다.
컴포넌트 및 해당 생명 주기 훅와 마찬가지로
각 Vue 지시문에는 트리거 가능한 자신만의 훅이 있습니다.
지시어 후크는 Vue 2와 Vue 3가 상당히 다릅니다.
Vue 2 directive 훅은 다음과 같습니다.
- bind – directive가 엘리먼트에 바인딩될 때 한 번 호출됩니다.
- insert - 바인딩된 요소가 부모 노드에 삽입될 때
- update – 요소가 업데이트될 때(그러나 자식이 아직 업데이트되지 않은 경우)
- componentUpdated – 자식도 업데이트한 후
- unbind – 지시문이 요소에서 바인딩 해제될 때 한 번 호출됩니다.
Vue 3 directive 훅은 다음과 같습니다.
- created – 요소의 props 또는 이벤트 리스너가 적용되기 전에 호출됩니다. (정적)
- beforeMount – Vue2 bind 훅과 동일, 엘리먼트에 바인딩될 때 한 번 호출됩니다.
- mounted - Vue2 inserted 훅과 동일, 바인딩된 요소가 부모 노드에 삽입될 때 호출됩니다.
- beforeUpdate – 요소 자체가 업데이트되기 전에 호출됩니다 (예: 라이프싸이클 훅).
- updated – Vue2 componentUpdated 훅과 동일, 자식도 업데이트 한 후 호출됩니다.
- beforeUnmount – 요소가 마운트 해제되기 전에 호출됩니다(예: 라이프사이클 훅).
- unmounted – 이전 언바인드 후크와 동일
- el – directive는 이 요소에 바인딩됩니다. 수정할 수 있는 액세스 권한을 제공합니다.
- binding – 많은 속성이 포함된 객체입니다. 잠시 후에 좀 더 알아봅니다.
- vnode – 가상 노드
- prevVnode – 이전 가상 노드(업데이트 훅에서만 사용 가능)
지시문에 대한 Vue 문서의 중요한 참고 사항(Vue docs for directives )은
이러한 인수(el 제외)를 읽기 전용으로 처리하고 절대 수정하지 않아야 한다는 것입니다.
The Binding Object
- name – directive 이름(v- 접두사 없음)
- value – directive에 전달된 값
- oldvalue – directive의 이전 값(업데이트 후크에서만 사용 가능)
- expression – 문자열에 바인딩된 표현식(예: v-direc=”3 * 3″, expression = “3*3”)
- arg – 문자열에 전달된 모든 인수(예: V-directc:blue, arg = blue)
- modifiers - 객체로 전달된 모든 수정자(예: V-directec.blue.link, modifiers = {blue: true, link: true}
Directive 정의하기
// Vue 2
Vue.directive("font-size", {
bind: (el, binding) => {
el.style.fontSize = 24 + "px";
},
updated: (el, binding) => {
el.style.fontSize = 24 + "px";
},
});
// Vue 3
app.directive("font-size", {
beforeMount: (el, binding) => {
el.style.fontSize = 20 + "px";
},
updated: (el, binding) => {
el.style.fontSize = 20 + "px";
},
});
컴포넌트 파일 내부에 다음 두 줄을 추가하면 컴포넌트가 작동하는 것을 볼 수 있습니다.
Directive를 선언할 때마다 접두사 v-를 사용하여 지시문에 액세스할 수 있습니다.
<p>Default Font Size</p>
<p v-font-size>Modified Font Size</p>
Vue 지시문을 정의하는 또 다른 방법이 있습니다.
main.js 내에서 이 구문을 사용할 수도 있습니다.
// pass a function!
app.directive("font-size", (el, binding) => {
el.style.fontSize = 24 + "px";
});
객체 대신 함수를 전달하면 bind(beforeMount), update(updated) 훅 중에 실행됩니다.
어떤 방법을 사용하든 결과는 다음과 같아야 합니다.
첫 번째 커스텀 Directiver가 동작 중입니다!
이제 이것을 조금 더 발전시켜 봅시다.
Directive에 인수 전달하기
지시문에 더 많은 제어를 추가하는 몇 가지 방법이 있습니다.
이것은 추가 값, 인수 또는 modifier를 전달하여 수행할 수 있습니다.
이 예에서 요소의 글꼴 크기를 더 잘 제어하기를 원한다고 가정해 보겠습니다.
반응형 데이터 - 값 전달하기 : binding.value
<p v-font-size='12'>Uses font-size directive</p>
<!-- OR USE A VARIABLE -->
<p v-font-size='fontSize'>Uses font-size directive</p>
app.directive('font-size', (el, binding, vnode) => {
el.style.fontSize = binding.value + 'px'
})
디렉티브로 인수 전달하기 binding.arg
반응성이 필요하지 않고 Directive에 여러 옵션을 제공하는 방법을 원하는 경우.
인수는 그렇게 하는 좋은 방법입니다.
구현은 다음과 같이 됩니다
app.directive('font-size', (el, binding, vnode) => {
console.log(binding + ' ' + vnode)
var size = 16
switch (binding.arg) {
case 'small':
size = 8
break
case 'large':
size = 32
break
default:
size = 16
break
}
el.style.fontSize = size + 'px'
})
템플릿은 아래와 같이 변경합니다.
<p v-font-size:small>Small</p>
<p v-font-size:medium>Medium</p>
<p v-font-size:large>Large</p>
modifier 사용하기
modifier는 반응성에 적합하지 않다는 점에서 인수와 유사합니다.
그러나 인수와 함께 사용하면 매우 맞춤화된 시스템을 만들 수 있습니다.
directive에 여러 modifier를 적용할 수 있기 때문입니다.
먼저 directive의 구현을 보겠습니다.
if 및 else-if의 순서는 modifier의 우선순위에 따라 다릅니다.
Vue.directive("font-size", (el, binding, vnode) => {
console.log(binding + " " + vnode);
var defaultSize;
if (binding.modifiers.small) {
defaultSize = 12;
} else if (binding.modifiers.large) {
defaultSize = 32;
} else {
defaultSize = 16;
}
if (binding.modifiers.red) {
el.style.color = "#ff0000";
}
el.style.fontSize = defaultSize + "px";
});
<p v-font-size.small.red>Small</p>
<p v-font-size.medium>Medium</p>
<p v-font-size.large>Large</p>
'FrontEnd' 카테고리의 다른 글
Remix의 데이터 플로우[Data Flow in Remix] (0) | 2022.10.07 |
---|---|
Vue.js plugin(플러그인) 만들어보기 (0) | 2022.10.07 |
Vue3과 React 훅의 반응성 비교 : 불변 VS 가변 (0) | 2022.10.06 |
Vue3의 렌더링 메커니즘 알아보기 (0) | 2022.10.06 |
Vue3 Reactivity In Depth (뷰3의 반응성 원리 이해하기) (0) | 2022.10.06 |