[Vue3] Custom Directives 적용하기

ljk4268·2023년 10월 12일

➕LEVELUP(Vue3)

목록 보기
6/6

진행하고 있는 프로젝트에 ImagelazyLoading을 적용시키면서
해당 기능을 directive로 만들어 봤다.

Custom Directives란?

v-if, v-for와 같은 나만의 디렉티브를 만들 수 있는 기능이다.

참고: https://vuejs.org/guide/reusability/custom-directives.html

Custom Directives 적용기

나는 커스텀 디렉티브를 전역적으로 사용하기 위해
전역적으로 등록했다.

1. directive 만들기

src > directives > lazyLoad.js

lazyLoad.js 파일

// lazyLoad.js
export default {
  mounted(el) {
    // Intersection Observer를 지원하지 않는 브라우저의 경우
    // backgroundImage에 바로 이미지 로딩시켜줌
    const loadBackgroundImage = () => {
      if (el.className.includes('lazy')) {
        const imageUrl = el.dataset.imageurl;
        el.style.backgroundImage = `url(${imageUrl})`;
      }
    };

    // Intersection Observer를 지원하는 브라우저의 경우
    // Observer 관찰자 만들어 
    // 스크롤에 따라 이미지 로딩할 수 있도록 만들어줌 
    const createObserver = () => {
      const observerOption = {
        root: null, // 뷰포트를 기준으로 관찰
        rootMargin: '0px 0px 100px 0px', // 아래로 100px까지는 관찰 대상으로 간주
        threshold: 0.5, // 관찰 대상의 50% 이상이 보일 때 콜백 호출
      };
      const observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            loadBackgroundImage();
            observer.unobserve(el);
          }
        });
      }, observerOption);
      observer.observe(el)
    };

    window['IntersectionObserver']
      ? createObserver()
      : loadBackgroundImage();
  },
};

✔️참고하면 좋을 팁! Directive Hooks
디렉티브 정의 객체는 다음과 같은 여러 훅을 사용할 수 있다.
모든 훅은 필수 아닌 선택!( 나의 경우 mounted()훅을 사용함 )

const myDirective = {
// 바인딩된 요소의 속성 전에 호출됨
// 또는 이벤트 리스너가 적용됨
created(el, binding, vnode, prevVnode) {
// 인수에 대한 자세한 내용은 아래를 참조하십시오.
},
// 요소가 DOM에 삽입되기 직전에 호출됩니다.
beforeMount() {},
// 바인딩된 요소의 부모 구성 요소가 있을 때 호출됩니다.
// 모든 자식이 마운트됩니다.
mounted() {},
// 상위 컴포넌트가 업데이트되기 전에 호출됨
beforeUpdate() {},
// 상위 컴포넌트 다음에 호출되고
// 모든 자식이 업데이트되었습니다.
updated() {},
// 상위 컴포넌트가 마운트 해제되기 전에 호출됨
beforeUnmount() {},
// 상위 컴포넌트가 마운트 해제될 때 호출됩니다.
unmounted() {}
}
}

2. directive 등록하기

src > main.js

import lazyLoad from './directives/lazyLoad.js'
app.directive('lazyLoad', lazyLoad)

위처럼 작성하면 directive가 등록된다.
등록한 directive를 사용하고 싶으면 v-if, v-for처럼 'v'접두사를 붙여 사용하면 된다.

<div v-lazy-load>
	필요한 코드 작성
</div>

수많은 구글링의 합작이지만
lazyLoading과 customDirective를 합쳐서 하나 만들어내니
괜시리 으쓱해졌다 으쓱으쓱..헿 😁

profile
적응중

0개의 댓글