複数のページやコンポーネントで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操作が必要な場合に使用されます。
oldVnode: 前回レンダリングされた仮想ノード
4. componentUpdated(el, binding, vnode, oldVnode)
説明: バインドされた要素の属性または値が更新され、子コンポーネントもすべて更新された後に呼び出されます。
つまり、最終的なDOMの状態で行われます。子コンポーネントの値が変わるのを待ってから実行されます。
5. unbind(el, binding, vnode)
説明: ディレクティブが要素に適用されなくなり、要素が破棄されるときに呼び出されます。
この時点でイベントリスナーを削除したり、クリーンアップ処理を行います。
* scrollカスタムサンプルでも、unbind時点でイベントリスナーをクリーンアップしています。