Rudchyk
7/22/2017 - 1:58 PM

v-click-outside directive https://jsfiddle.net/Linusborg/Lx49LaL8/

v-click-outside directive https://jsfiddle.net/Linusborg/Lx49LaL8/

new Vue({
  el: '#app',
  data: {
  	clickOutside: 0,
    clickInside: 0,
  },
  methods: {
    outside: function(e) {
    	this.clickOutside += 1
        console.log('clicked outside!')
      },
      inside: function(e) {
        this.clickInside += 1
        console.log('clicked inside!')
      }
  },
  directives: {
    'click-outside': {
      bind: function(el, binding, vNode) {
        // Provided expression must evaluate to a function.
        if (typeof binding.value !== 'function') {
        	const compName = vNode.context.name
          let warn = `[Vue-click-outside:] provided expression '${binding.expression}' is not a function, but has to be`
          if (compName) { warn += `Found in component '${compName}'` }
          
          console.warn(warn)
        }
        // Define Handler and cache it on the element
        const bubble = binding.modifiers.bubble
        const handler = (e) => {
          if (bubble || (!el.contains(e.target) && el !== e.target)) {
          	binding.value(e)
          }
        }
        el.__vueClickOutside__ = handler

        // add Event Listeners
        document.addEventListener('click', handler)
			},
      
      unbind: function(el, binding) {
        // Remove Event Listeners
        document.removeEventListener('click', el.__vueClickOutside__)
        el.__vueClickOutside__ = null

      }
    }
  }
})
<div id="app">
  <div class="test" v-click-outside="outside" @click="inside">Test</div>
  <!--<div class="test" v-click-outside.bubble="outside" @click="inside">Test</div>-->
  Add the .bubble modifier to the directive to make clicks inside bubble up.
  <pre>
    {{$data}}
  </pre>
</div>
.test {
  padding: 50px;
  border: 1px solid black;
  margin: 50px;
  background-color: white;
  cursor: pointer;
}