v-click-outside Vue directive
detect a click outside of an element
by luka kupunia
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/0.7.10/vue-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.1.2/foundation.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.js"></script>
<div id="app">
<div class="callout" >
<button @click.stop="show" class="button secondary">Click me</button>
<div class="callout" v-if="showInside" v-click-outside="closeEvent">
<p>This is the Inside. You can click inside of here and nothing happens. You close with the button below, or by clicking outside the box.</p>
<p>If you click outside of this box, the event defined via the <i>v-click-outside</i> directive will be emitted.</p>
<p>Caveat: The Event that makes this box show ("Click me") has to use the .stop modifier, otherwise the event set up by <i>v-click-outside</i> will catch it, and $emit the custom event prematurely </p>
<button class="button" @click="hide">Close</button>
</div>
</div>
</div>
Babel + JSX
Vue.directive('click-outside', {
bind () {
let self = this
this.event = function (event) {
console.log('emitting event')
self.vm.$emit(self.expression,event)
}
this.el.addEventListener('click', this.stopProp)
document.body.addEventListener('click',this.event)
},
unbind() {
console.log('unbind')
this.el.removeEventListener('click', this.stopProp)
document.body.removeEventListener('click',this.event)
},
stopProp(event) {event.stopPropagation() }
})
var App = new Vue({
el: '#app',
data() {
return {
showInside: false
}
},
methods:{
show: function () {
this.showInside = true
},
hide: function () {
console.log('hide')
this.showInside = false
}
},
events: {
closeEvent: function () {
console.log('close event called')
this.hide()
}
}
})