1

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?

1 Answer 1

5

try this

...
methods:{
  clickYears: function(event){
    this.$refs.Years.show = true
    event.stopPropagation();
  }
}
...
Sign up to request clarification or add additional context in comments.

2 Comments

You, my friend, are a genius. So I guess this stops the event from propagating all they way up to the close event listener that's on the body element. Very nice. Thank you!
Actually it prevents propagating close event to the btn. see more at developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.