I am wondering how can we hide all shown elements on click outside from those elements in vue:
<button @click="div1=true">Show div 1</button>
<div v-if="div1">DIV 1</div>
<button @click="div2=true">Show div 2</button>
<div v-if="div2">DIV 2</div>
How can I hide all divs besides div 1 if I click on div 1 or hide all divs on click on some random part of the page? How does vuetify handle it?
I am wondering how can we hide all shown elements on click outside from those elements in vue:
<button @click="div1=true">Show div 1</button>
<div v-if="div1">DIV 1</div>
<button @click="div2=true">Show div 2</button>
<div v-if="div2">DIV 2</div>
How can I hide all divs besides div 1 if I click on div 1 or hide all divs on click on some random part of the page? How does vuetify handle it?
Share Improve this question asked Feb 25, 2019 at 20:30 LearnerLearner 7733 gold badges13 silver badges38 bronze badges 4- Just detect the click outside with a directive and iterate through the open divs and set their display/hide property to false. – Steven B. Commented Feb 25, 2019 at 20:36
-
does not work for me even tho it works in fiddle I get
Cannot set property 'event' of undefined
– Learner Commented Feb 25, 2019 at 20:43 - Did you look at the specific answer I linked? not the selected answer of the question as that was for vue 1.x. – Steven B. Commented Feb 25, 2019 at 20:46
- @StevenB. yes i did – Learner Commented Feb 25, 2019 at 20:48
4 Answers
Reset to default 1Vue way is to use this.$el
(DOM element of current ponent), you can change this.$el
and use any other HTMLElement
<div class="modal" @click="handleClick">
<div class="modal-dialog">
<div class="modal-content">
...
</div>
</div>
And method should look like this
handleClick(e: Event): void {
if (e.target instanceof HTMLElement && !this.$el.contains(e.target)) {
this.$emit("hide"); //fires only on click outside
}
}
It's easy to detect click outside of the element if you know how event bubbling works in DOM.
Hiding other divs works perfectly well when you put state of every div into the ponents's state.
Here is an example: https://codesandbox.io/s/0480m38mww?fontsize=14&module=%2Fsrc%2FApp.vue
Learn more about Event Bubbling here - https://javascript.info/bubbling-and-capturing
I used this process so Home ponent would know that outside my Nav ponent has been clicked. It helps that I have my nav inside my Home Component.
My Home ponent template:
<div>
<nav-bar ref="nav"></nav-bar>
<div @click="useHideNavMethod()">
So I use ref="nav"
to use methods from the Nav in my Home ponent. This means I can use the hideNav() method (which resides in Nav).
I have purposely put the nav outside of this div with the click method, so anywhere clicked other than Nav would initiate the useHideNavMethod() function.
In my Nav ponent template I have:
<nav id="nav">
which is referenced when I use ref="nav"
.
So inside my hideNav() I have this.styleNavLi.display = 'none';
so it would hide the nav bar.
So all I need to do to use that method in Home is to use:
useHideNavMethod() {
this.$refs.nav.hideNav();
}
Use div1 = !div1
for toggle view,
Or use div1 = true
for one time only.
<template>
<div>
{{ div1 }}
<button @click="div1 = !div1">Show div 1</button>
<div v-if="div1">DIV 1</div>
{{ div2 }}
<button @click="div2 = !div2">Show div 2</button>
<div v-if="div2">DIV 2</div>
</div>
</template>
<script>
export default {
data() {
return {
div1: true, // set default value as you want
div2: false,
};
},
};
</script>