Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to hide dropdown menu if we click outside the menu in vuejs

I am using a dropdown menu components in vuejs to make normal dropdown menu. My code is for dropdown component is :

<template>
    <span class="dropdown" :class="{shown: state}">
        <a href="#" @click.prevent="toggleDropdown" class="dropdown-toggle">toggle menu</a>
            <div class="dropdown-menu" v-show="state">
                <ul class="list-unstyled">
                    <slot></slot>
                </ul>
            </div>
        </transition>
    </span>
</template>

<script>
export default {
    name: 'dropdown',
    data () {
        return {
            state: false
        }
    },
    methods: {
        toggleDropdown (e) {
            this.state = !this.state;
        }
    }
}
</script>

Now I am importing the dropdown component in my VUE app at various place by using following code in the template

<dropdown>
    <li>
         Action
    </li>
</dropdown>

Now that is working fine but I want that only one dropdown should be active at the same time.

I have done little research and found that i can use plugins like https://github.com/davidnotplay/vue-my-dropdown but I don't want to use that. Again i have also studied how the above example works but I want to implement this dropdown functionality in such a way that my dropdown component would take care of all event related to dropdown. So can you help me how to achieve that?

like image 251
Rakesh Soni Avatar asked Sep 04 '17 14:09

Rakesh Soni


People also ask

How do I hide dropdown on click outside?

Answer: Use the jQuery on() method You can use the jQuery click() method in combination with the on() method to hide the dropdown menu when the user click outside of the trigger element.

How do I make modal close on click outside Vue?

By default, dialog can be closed by pressing Esc key and clicking the close icon on the right of dialog header. It can also be closed by clicking outside of the dialog using hide method. Set the CloseOnEscape property value to false to prevent closing of the dialog when pressing Esc key.

How do I hide components in Vue?

Vue gives you a bunch of good ways to hide the element on the screen. When using v-if="false" the element isn't rendered at all in the DOM. When using v-show="false" the element is rendered in the DOM, however, Vue applies the inline style display: none that hides the element completely.

What is $V in Vue?

$v is an object that calls vuelidate (at the time of writing the comment, supported in version Vue.


2 Answers

I know it's quite an old question but I think the best way to do that without any external plugins is to add a click listener to mounted lifecycle hook (and remove it on beforeDestroy hook) and filter the clicks on your component so it only hides when clicked outside.

<template>
    <span class="dropdown" :class="{shown: state}">
      <a href="#" @click.prevent="toggleDropdown" class="dropdown-toggle">toggle menu</a>
            <div class="dropdown-menu" v-show="state">
                <ul class="list-unstyled">
                    <slot></slot>
                </ul>
            </div>
        <transition/>
    </span>
</template>

<script>
export default {
  name: 'dropdown',
  data () {
    return {
      state: false
    }
  },
  methods: {
    toggleDropdown (e) {
      this.state = !this.state
    },
    close (e) {
      if (!this.$el.contains(e.target)) {
        this.state = false
      }
    }
  },
  mounted () {
    document.addEventListener('click', this.close)
  },
  beforeDestroy () {
    document.removeEventListener('click',this.close)
  }
}
</script>
like image 191
kgolinski Avatar answered Oct 06 '22 10:10

kgolinski


Have a look at vue-clickaway.(Link)

Sometimes you need to detect clicks outside of the element (to close a modal window or hide a dropdown select). There is no native event for that, and Vue.js does not cover you either. This is why vue-clickaway exists. Please check out the demo before reading further.

like image 31
Shubham Patel Avatar answered Oct 06 '22 09:10

Shubham Patel