2024年11月26日
最近はAlpine.jsでなくVueを弄っている。
Alpine.jsには@click.outsideという便利メソッドがあるんだけど、Vueにはなかった。
無くて困っていたところ、自分でディレクティブを作る方法で上手くいったので残す。
独自ディレクティブを定義する
私はLaravel環境でVueを使っているので、resources/js/Directives/clickOutSide.js
と作成。
中身は以下のようにする。
export default {
beforeMount(el, binding) {
el.clickOutsideEvent = (event) => {
if (!(el === event.target || el.contains(event.target))) {
binding.value();
}
};
document.addEventListener("click", el.clickOutsideEvent);
},
unmounted(el) {
document.removeEventListener("click", el.clickOutsideEvent);
},
};
beforeMount()やunmounted()は公式ドキュメントにある通り、要素が作成されたり削除されたりしたときに呼び出されるフック。
各フックの引数el
はディレクティブが付いている要素自身を示し、binding.value
はディレクティブに渡される値を示す。
つまり、v-click-outside="() => console.log('クリック')"
とすればbinding.value
はアロー関数となり、binding.value()
で実行される感じ。
カスタムディレクティブをグローバルで登録する
続いて、先に作ったカスタムディレクティブをVueに登録する。
これはVueのアプリケーションインスタンスを作るときに登録してあげればおk。
import clickOutside from "@/Directives/clickOutside";
const app = createApp({})
app.directive("click-outside", clickOutside)
作ったclick-outsideを使ってみる
グローバルレベルで登録しているので、いきなり使ってしまって問題ない。
利用するときはv-[ディレクティブ名]
で利用する。
<script setup>
const hi = () => {
console.log("こんにちは!");
}
</script>
<template>
<div v-clicl-outside="hi">
要素内
</div>
</template>
これでdivの外側をクリックするとコンソールに出力されるのが確認できると思う。
以上です。