여러 페이지나 컴포넌트들에서 공통적으로 DOM에 적용되는 기능들을
- 메인화면이나 상세 페이지 등에서 스크롤 시 데이터 로딩, 스크롤 시 토스트 띄우기 등 유용하다.
1. 먼저, 파일을 만들고 nuxt plugin에 등록한다.
// nuxt.config.js
export default {
plugins: [
'~/plugins/v-scroll.js', // 플러그인 등록
],
}
nuxt config plugins는 정의된 파일들을 Nuxt 애플리케이션이 초기화될 때 실행하여 특정 동작을 활성화한다. = 특정 기능을 전역에서 사용할 수 있다.
2. 스크롤 디렉티브를 구현한다.
// plugins/v-scroll.js
import Vue from 'vue';
// 커스텀 디렉티브 등록
Vue.directive('scroll', {
inserted(el, binding) {
const callback = binding.value.callback; // 전달된 콜백 함수
const offset = binding.value.offset || 0; // 사용자 지정 오프셋 (기본값 0)
// 스크롤 이벤트 핸들러
const onScroll = () => {
const scrollPosition = window.scrollY + window.innerHeight;
const elementPosition = el.offsetTop + offset;
if (scrollPosition >= elementPosition) {
callback();
}
};
// 스크롤 이벤트 리스너 등록
window.addEventListener('scroll', onScroll);
// 엘리먼트 언바인드 시 이벤트 리스너 제거
el._onScroll = onScroll;},
unbind(el) {
// 스크롤 이벤트 리스너 제거
window.removeEventListener('scroll', el._onScroll);
delete el._onScroll;
}
});
컴포넌트에서 콜백함수를 넘길 수 있도록 구현한다.
3. 이제 페이지에서 v-scroll을 사용한다.
<template>
<div v-scroll="{callback: loadMore, offset: 100}">
</div>
</template>
<script>
export default {
//...생략
methods: {
loadMore() {
//get more data (fetch, axios etc...)
}
}
}
</script>
기타
커스텀 디렉티브를 만들 때 쓸 수 있는 훅들이 몇 가지 있다.
1. bind(el, binding, vnode)
설명: 디렉티브가 처음으로 엘리먼트에 바인딩될 때 한 번만 호출한다.
여기서 바인딩된 요소에 초기 설정을 할 수 있다.
el: 디렉티브가 바인딩된 DOM 요소
binding: 디렉티브의 값, 표현식, 아규먼트 등을 담고 있는 객체
vnode: Vue 컴파일러에서 생성한 가상 노드
Vue.directive('color', {
bind(el, binding) {
// 디렉티브가 바인딩될 때 텍스트 색상 설정
el.style.color = binding.value;
}
});
2. inserted(el, binding, vnode)
설명: 바인딩된 요소가 DOM에 삽입되었을 때 호출된다. 즉, 디렉티브가 DOM에 실제로 추가되었을 때 사용된다.
* 스크롤 이벤트 바인딩 코드에 보면, inserted 훅 시점에 DOM 관련 작업을 수행한다.
3. update(el, binding, vnode, oldVnode)
설명: 바인딩된 요소의 속성이나 값이 변경될 때마다 호출된다.
단, 아직 자식 컴포넌트들이 업데이트되기 전의 상태이다.
바인딩 값이 변경될 때 DOM 수행이 필요한 경우 사용된다.
4. componentUpdated(el, binding, vnode, oldVnode)
설명: 바인딩된 요소의 속성 또는 값이 업데이트되고 자식 컴포넌트까지 모두 업데이트된 후 호출된다.
즉, 최종 DOM 상태에서 수행된다. 자식 컴포넌트 값이 바뀌는 것을 기다린 다음 수행한다.
5. unbind(el, binding, vnode)
설명: 디렉티브가 더 이상 요소에 적용되지 않으며, 요소가 파괴될 때 호출된다.
이 시점에서 이벤트 리스너를 제거하거나, 정리 작업을 한다.
* scroll 커스텀 샘플에도 unbind 시점에서 이벤트 리스너를 정리한다.