4

I have a nuxt project. I need to write a click-outside directive by which I can detect outside clicks of elements to close them. How can I implement it?

Shadi Farzankia
  • 639
  • 8
  • 21
  • Actually I editted it before the answer. So I don't see any problem here. The answer is voted towice after editing the question. But thanks for informing me. I double checked it – Shadi Farzankia Sep 17 '20 at 12:56

4 Answers4

11

The answer is to create a directives.js file in your plugins and register it in the config.nuxt.js file. The content of the directives.js file is as follows:

import Vue from 'vue';

Vue.directive('click-outside', {
    bind: function (el, binding, vnode) {
    el.clickOutsideEvent = function (event) {
        // here I check that click was outside the el and his childrens
        if (!(el == event.target || el.contains(event.target))) {
        // and if it did, call method provided in attribute value
        vnode.context[binding.expression](event);
        }
    };
    document.body.addEventListener('click', el.clickOutsideEvent)
    },
    unbind: function (el) {
    document.body.removeEventListener('click', el.clickOutsideEvent)
    },
});

Then you can use it on any element that you want and execute your function.

For Example:

<div v-click-outside="closeDropdown"></div>
Anbuselvan Rocky
  • 606
  • 6
  • 22
Shadi Farzankia
  • 639
  • 8
  • 21
  • 2
    This is giving me the error: ``` v-click-outside.js?015b:9 Uncaught TypeError: vnode.context[binding.expression] is not a function at HTMLBodyElement.el.clickOutsideEvent ``` – Bonteq Aug 16 '21 at 16:30
  • 1
    It is maybe worth mentioning: If the element targeted with the "v-click-outside" directive contains a – Leopold Kristjansson Oct 26 '21 at 21:46
-1

This is a common JS issue, you can try to solve it with this: https://stackoverflow.com/a/36696086/4239703

You can register the handler on mounted() lifecycle hook for example.

jumper85
  • 472
  • 3
  • 9
-1
import Vue from 'vue'
 
Vue.directive('click-outside', {
 bind: function (el, binding, vnode) {
   el.clickOutsideEvent = function (event) {
     // here I check that click was outside the el and his children
     if (!(el == event.target || el.contains(event.target))) {
       // and if it did, change data from directive
       vnode.context.isDropdwonMenuVisible = false;
     }
   };
   document.body.addEventListener('click', el.clickOutsideEvent)
 },
 unbind: function (el) {
   document.body.removeEventListener('click', el.clickOutsideEvent)
 },
});


<a v-click-outside>Link</a>


data() {
    return {
      isDropdwonMenuVisible: true,
    };
  },

nuxt.config.js

plugins: [
  '~/plugins/click-outside.js'
]
atazmin
  • 4,757
  • 1
  • 32
  • 23
-1

Just use this to change the state.

v-on:focusout=""
David
  • 1
  • 1