본문 바로가기

FrontEnd

Vue.js 커스텀 Directive 만들어보기

반응형

뭔가를 배우는 최고의 방법은 직접 만들어 보는 것입니다.

Vue.js의 Directive를 직접 만들며 배워봅니다.

원문 : https://learnvue.co/tutorials/vue-custom-directives

 

Creating Your First Vue Custom Directive - with Vue 3 Updates - LearnVue

Last Updated on Jan 10, 2020

learnvue.co

Vue에서 Directive는 DOM을 직접 편집하는 가장 좋은 방법 중 하나입니다.
몇 가지 예로는 v-if, v-show, v-bind 등이 있습니다.
Vue를 사용한 적이 있다면 directive에 익숙할 것입니다.
Vue 사용자 지정 지시문은 Vue에서 프로젝트에 추가 지시문을 만들 수 있는 방법입니다.
프로젝트 전체에 고유하고 재사용 가능한 기능을 추가할 수 있는 좋은 방법입니다.
Vue 커스텀 Directive은 DOM의 반응성을 처리할 뿐만 아니라 요소를 조작할 수 있습니다.
 
우리는 다음을 배우게 됩니다.
  • 사용자 지정 지시문이란
  • Vue 지시자의 다양한 이벤트 훅
  • 사용자 지정 지시문을 만드는 방법

Custom Directive란?

커스텀 디렉티브는 프로젝트를 당신의 필요에 맞게 만드는 방법입니다.
Vue 플러그인을 사용하는 경우 커스텀 디렉티브를 꽤 자주 사용한다는 것을 알 수 있습니다.

 

예를 들어, v-lazy plugin에서 v-lazy 지시문을 사용하여 이미지 로딩을 보다 효과적으로 만드는 커스터마이징 기능을 추가합니다.
DOM을 직접 편집하고 싶기 때문에 디렉티브를 사용하는 것이 가장 좋은 경우입니다.

computed 및 watchers를 사용하면 안되나요?

컴포넌트 옵션이 추상화 및 코드 재사용에 유용하지만
사용자 지정 지시문은 여전히 ​​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 정의하기

main.js 파일 내부 또는 Vue 인스턴스가 정의된 모든 곳에서
Vue 2의 Vue.directive 메서드
또는 Vue 3의 app.directive 메서드를 사용하기만 하면 됩니다.
컴포넌트의 font 크기를 조작할 수 있는 지시문을 만들어 보겠습니다. v-font-size라고 합니다.
main.js 내부에 beforeMount 및 updated 훅을 수신하고 글꼴 크기를 조정하는 코드를 추가합니다.
// 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";
  },
});​
지금부터 Vue3을 이용해 훅을 만들어 보겠습니다.

컴포넌트 파일 내부에 다음 두 줄을 추가하면 컴포넌트가 작동하는 것을 볼 수 있습니다.
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

데이터를 전달하는 가장 직관적인 방법은 값을 할당하는 것입니다.
이렇게 하면 값이 변경될 때마다 Directive가 반응적으로 업데이트될 수 있습니다.
이것은 또한 다양한 값(모든 글꼴 크기)을 수용할 수 있기 때문에 가장 유연한 제어를 제공합니다.
컴포넌트에서는 아래와 같이 선언합니다.
<p v-font-size='12'>Uses font-size directive</p>
<!-- OR USE A VARIABLE -->
<p v-font-size='fontSize'>Uses font-size directive</p>
그리고 Directive 구현에서 binding 개체의 값을 사용하도록 메서드를 변경합니다.
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>
출력은 세 가지 모두 다음과 같아야 합니다.

축하합니다!
이제 여러분은 Vue Directive를 개발할 수 있습니다!
해피 코딩!
 
더 볼만한 게시물 :
반응형