JAVASCRIPT

Building a Custom Vue 3 Directive for Click-Outside Detection

Develop a custom Vue 3 directive to easily detect clicks outside a specific DOM element. This pattern is perfect for dismissing modals, dropdowns, or closing popovers with enhanced reusability.

import { DirectiveBinding } from 'vue';

// Define the custom directive
const vClickOutside = {
  mounted(el, binding) {
    el.__clickOutsideHandler__ = (event) => {
      // Check if click is outside the element and not on a child of the element
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event);
      }
    };
    document.addEventListener('click', el.__clickOutsideHandler__);
  },
  unmounted(el) {
    document.removeEventListener('click', el.__clickOutsideHandler__);
    delete el.__clickOutsideHandler__;
  }
};

// Usage in main.js or a plugin (example for main.js):
// import { createApp } from 'vue';
// import App from './App.vue';
// import vClickOutside from './directives/v-click-outside'; // Assuming the directive is in its own file

// const app = createApp(App);
// app.directive('click-outside', vClickOutside);
// app.mount('#app');

// Usage in a Vue component:
// <template>
//   <div class="my-dropdown-container" v-click-outside="closeDropdown">
//     <button @click="toggleDropdown">Toggle Dropdown</button>
//     <div v-if="isOpen" class="dropdown-content">
//       Dropdown content here...
//     </div>
//   </div>
// </template>

// <script setup>
// import { ref } from 'vue';

// const isOpen = ref(false);

// const toggleDropdown = () => {
//   isOpen.value = !isOpen.value;
// };

// const closeDropdown = () => {
//   if (isOpen.value) {
//     isOpen.value = false;
//     console.log('Clicked outside! Dropdown closed.');
//   }
// };
// </script>
How it works: This code defines a custom Vue 3 directive, `v-click-outside`, enabling components to easily detect when a user clicks anywhere outside the element it's applied to. In `mounted`, it attaches a global click event listener, storing the handler on the element itself (`el.__clickOutsideHandler__`). The handler checks if the click originated outside `el` and its children. In `unmounted`, the listener is properly removed to prevent memory leaks. This directive is ideal for implementing UI patterns like auto-closing dropdowns or modals.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs