JAVASCRIPT
Creating a Custom Vue 3 Directive for Click Outside
Implement a custom Vue 3 directive to detect clicks outside an element, perfect for closing dropdowns, modals, or context menus efficiently.
// directives/click-outside.js
const clickOutside = {
beforeMount(el, binding) {
el.clickOutsideEvent = function (event) {
// Check if click was outside the element and not on the element itself
if (!(el === event.target || el.contains(event.target))) {
// Execute the provided method
binding.value(event);
}
};
document.addEventListener('click', el.clickOutsideEvent);
},
unmounted(el) {
document.removeEventListener('click', el.clickOutsideEvent);
},
};
export default clickOutside;
// main.js (or any entry point)
import { createApp } from 'vue';
import App from './App.vue';
import ClickOutside from './directives/click-outside';
const app = createApp(App);
app.directive('click-outside', ClickOutside);
app.mount('#app');
// Component.vue
<template>
<div class="dropdown">
<button @click="isOpen = !isOpen">Toggle Dropdown</button>
<div v-if="isOpen" v-click-outside="closeDropdown" class="dropdown-content">
Dropdown content here
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const isOpen = ref(false);
const closeDropdown = () => {
isOpen.value = false;
};
</script>
<style scoped>
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
padding: 12px;
z-index: 1;
border: 1px solid #ddd;
}
</style>
How it works: This snippet demonstrates creating and using a custom Vue 3 directive, `v-click-outside`. The directive attaches an event listener to the document when the element is mounted, checking if a click originated outside the element. If so, it executes the method provided to the directive (e.g., `closeDropdown`). Crucially, it cleans up the event listener when the element is unmounted to prevent memory leaks, making it ideal for managing dropdowns or modals.