Vue custom directive

by stephanv

HTML

<script src="https://vuejs.org/js/vue.min.js"></script>
<div id="vue">
  <datepicker></datepicker>
</div>

Babel + JSX

Vue.directive('click-outside', {
    bind(el, binding, vnode) {
        el.event = (event) => {
            // Check that click was outside the el and his children.
            if (!(el === event.target || el.contains(event.target))) {
                console.log('Clicked outside');

                // Call the method provided as the attribute value.
                vnode.context[binding.expression](event);
            }
        };

        document.body.addEventListener('click', el.event);
    },

    unbind(el) {
        document.body.removeEventListener('click', el.event);
    }
})

Vue.component('datepicker', {
  template: `
    <div>
      <div class="datepicker" v-if="visible" v-click-outside="hide">
        Datepicker example
      </div>

      <button type="button" @click="show">Show datepicker</button>
    </div>
  `,

  data() {
  	return {
      visible: false
    }
  },
  
  methods: {
    show() {
      this.visible = true;
    },
    
    hide() {
      this.visible = false;
    }
  }
})

new Vue({
  el: '#vue'
})