See this StackOverflow thread
First off, include the directive at the end of this gist.
- On your open button, make sure to use
@click.stop
to prevent the open click event from closing your modal. - On your modal, add the
v-click-outside
directive and points it at a function to call when clicked outside.
<template>
<button @click.stop="openPopupβ />
<div v-if="shouldShowModalβ v-click-outside="hidePopupβ />
</template>
<script>
export default {
data() {
return {
shouldShowModal: false
};
},
methods: {
showPopup() {
this.shouldShowModal = true;
},
hidePopup() {
this.shouldShowModal = false;
}
},
};
</script>
Based on this SO answer
Vue.directive(βclick-outsideβ,{
bind: function (el, binding, vnode) {
el.eventSetDrag = function () {
el.setAttribute('data-dragging', 'yes');
}
el.eventClearDrag = function () {
el.removeAttribute('data-dragging');
}
el.eventOnClick = function (event) {
var dragging = el.getAttribute('data-dragging');
// Check that the click was outside the el and its children, and wasn't a drag
if (!(el == event.target || el.contains(event.target)) && !dragging) {
// call method provided in attribute value
vnode.context[binding.expression](event);
}
};
document.addEventListener('touchstart', el.eventClearDrag);
document.addEventListener('touchmove', el.eventSetDrag);
document.addEventListener('click', el.eventOnClick);
document.addEventListener('touchend', el.eventOnClick);
}, unbind: function (el) {
document.removeEventListener('touchstart', el.eventClearDrag);
document.removeEventListener('touchmove', el.eventSetDrag);
document.removeEventListener('click', el.eventOnClick);
document.removeEventListener('touchend', el.eventOnClick);
el.removeAttribute('data-dragging');
},
});
Thanks for your solution, works great on Desktop! However on my Android phone browser it doesn't quite behave properly. If you click the button to open the dialog box it opens, but if you click the button again the dialog box attempts to close but then reopens again. Though clicking outside the button will close the dialog properly. Any ideas on what that could be?