JAVASCRIPT
Vue 3 Custom Directive for Click Outside
Implement a reusable Vue 3 custom directive to detect clicks occurring outside of a specific element, ideal for auto-closing dropdowns, modals, or menus.
// directives/click-outside.js
export default {
beforeMount(el, binding) {
el.__vueClickOutside__ = (event) => {
// Check if the clicked target is neither the element itself nor a descendant
if (!(el === event.target || el.contains(event.target))) {
// If click is outside, execute the provided handler function
binding.value(event);
}
};
// Attach event listener to the document
document.addEventListener('click', el.__vueClickOutside__);
},
unmounted(el) {
// Clean up the event listener when the component is unmounted
document.removeEventListener('click', el.__vueClickOutside__);
delete el.__vueClickOutside__;
},
};
// main.js (or your app entry file, for global registration)
import { createApp } from 'vue';
import App from './App.vue';
import ClickOutsideDirective from './directives/click-outside';
const app = createApp(App);
app.directive('click-outside', ClickOutsideDirective);
app.mount('#app');
<!-- Example usage in a component -->
<template>
<div v-click-outside="closeDropdown" class="dropdown-container">
<button @click="isOpen = !isOpen">Toggle Dropdown</button>
<div v-if="isOpen" class="dropdown-content">
<p>This is dropdown content.</p>
<p>Click outside to close me!</p>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const isOpen = ref(false);
const closeDropdown = () => {
isOpen.value = false;
console.log('Clicked outside the dropdown!');
};
</script>
<style scoped>
.dropdown-container {
position: relative;
display: inline-block;
margin: 20px;
}
.dropdown-content {
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
padding: 12px 16px;
z-index: 1;
border-radius: 4px;
}
</style>
How it works: This code implements a custom Vue 3 directive called `v-click-outside`. It attaches a global click event listener to the document. When a click occurs, the listener checks if the event target is outside the element to which the directive is bound. If it is, the handler function provided as the directive's value is executed. This pattern is extremely useful for common UI interactions like closing dropdowns, sidebars, or modals when a user clicks anywhere else on the page.