vue-dropmenu

by huigo

HTML

<script src="https://npmcdn.com/vue/dist/vue.js"></script>
<div id="app">
  <div style="position:relative">
    <button v-on:click.stop="showMenu = !showMenu">Menu</button>
    <dropdown-menu v-if="showMenu"
          v-on:close="showMenu = false"
          ></dropdown-menu>
  </div>
  <p>
    ボタンをクリックするとドロップダウンします
  </p>
</div>

<script type="text/x-template" id="menu-template">
	<div class="menu" style="position:absolute">
  	<div>AAA</div>
    <div>BBB</div>
    <div>CCC</div>
  </div>
</script>

CSS

.menu {
  background:#fff;
  box-shadow: 0 6px 12px rgba(0,0,0,0.175);
  padding: 5px;
}

JavaScript

var listener = {
	methods:{
    listen :function(target, eventType, callback) {
    	if (!this._eventRemovers){
      	this._eventRemovers = [];
      }
      target.addEventListener(eventType, callback);
      this._eventRemovers.push( {
        remove :function() {
          target.removeEventListener(eventType, callback)
        }
      })
  	}
  },
  destroyed:function(){
  	if (this._eventRemovers){
      this._eventRemovers.forEach(function(eventRemover){
        eventRemover.remove();
      });
    }
 }
}

Vue.component('dropdown-menu', {
	mixins:[listener],
  template: '#menu-template',
  created:function(){
    this.listen(window, 'click', function(e){
      if (!this.$el.contains(e.target)){
        this.$emit('close');
      }
    }.bind(this));
  }
});

new Vue({
    el: '#app',
    data: {
        showMenu: false
    }
})