Vue JS: Open Menu Component with Button, Close with Click Outside of Menu

Asked By: Anonymous

Vue JS 2.6.10

I have read a variety of SO posts about how to create a custom directive so that you can detect a click outside of a popup menu so you can close it. I can’t quite get it to work because I have a button that opens the menu and clicking it fires the “close” behavior.

Here’s my main view Logbook.vue that has the button that opens the menu:
enter image description here

// --- Logbook.vue ---
<script>
export default {
  name: 'Logbook',
  components:{
    Years
  },
  methods:{
    clickYears: function(){
      this.$refs.Years.show = true
    }
  }
}
</script>
<template>
  <div id="current-year">
    <a href="#year" ref="yearButton" v-on:click.prevent="clickYears">{{ currentYear }}</a>
    <Years ref="Years" v-on:selectYear="yearSelected" />
  </div>
</template>

Here is the menu component Years.vue that opens when you click the button:
enter image description here

//--- Years.vue ---
<script>
import Vue from 'vue'

//Custom directive to handle clicks outside of this component
Vue.directive('click-outside', {
  bind: function (el, binding, vnode) {
    window.event = function (event) {
      if (!(el == event.target || el.contains(event.target))) {
        vnode.context[binding.expression](event)
      }
    };
    document.body.addEventListener('click', window.event)
  },
  unbind: function (el) {
    document.body.removeEventListener('click', window.event)
  }
})

export default{
  name: 'Years',
  data() {
    return {
      show: false
    }
  },
  methods:{
    close: function(){
      this.show = false
    }
  }
}
</script>

<template>
  <div id="years" v-show="show" v-click-outside="close">
  <!-- Years listed here... -->
  </div>
</template>

The close method is firing appropriately when I click outside of the Years component, but the problem is that I can’t ever open the Years menu to begin with because clicking the button also fires the close behavior because it’s also outside of the Years component.

Has anyone overcome this problem? Any ideas?


Solution

Answered By: Anonymous

try this

...
methods:{
  clickYears: function(event){
    this.$refs.Years.show = true
    event.stopPropagation();
  }
}
...

Windows 10 Kaufen Windows 10 Pro Office 2019 Kaufen Office 365 Lizenz Windows 10 Home Lizenz Office 2019 Home Business Kaufen windows office 365 satın al follower kaufen instagram follower kaufen porno