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?
Asked
Active
Viewed 8,412 times
4
-
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 Answers
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
-
2This 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
-
1It 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
-
actually I would like to make it like a directive to use it in different components. – Shadi Farzankia Jan 18 '20 at 06:10
-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