Menu Dropdown (VUEJS / Javascript)

3

I'm trying to make a dropdown menu in Vue (I do not want to use Bootstrap-vue), so I created a isActiveDrop and set it to true , and every time I click the button to open it it's set to false , so the menu appears and disappears, but how would that menu disappear when clicking away? without having to click on the icon, just clicking outside it?

<i class="fa fa-menu" @click="menu"></i>

<ul  :class="{hidden: isActiveDrop}">
  <li>TESTE</li>
</ul>
    
asked by anonymous 30.06.2017 / 21:22

1 answer

3

Hello,

Looking for a simple way to implement the click-outside functionality in the element, I found this directive ". Alias, I did not find it any other way but by directives.

Below is an adaptation of directive to ES5 and a few more modifications.

Vue.directive('click-out', {
  bind: function(element, binding, node) {
    // verifica se o parametro da diretiva é diferente de um objeto do tipo function.
    if(typeof binding.value !== 'function') {
      var component = node.context.name;
      var text = '[Vue-click-out:] a expressão informada deve ser uma função';
      if(component) {
        text += ' Component: ' + component;
      };
      console.warn(text);
    };
    // cria o evento e atribui ao elemento
    var bubble = binding.modifiers.bubble;
    var handler = function(evt) {
      if(bubble || (!element.contains(evt.target) && element !== evt.target)) {
        binding.value(evt);
      };
    };
    element.__vueClickOutside__ = handler;
    // adiciona o evento que trata os cliques fora do component
    document.addEventListener('click', handler);
  },

  unbind: function(element) {
    // remove o evento que trata cliques fora do componente
    document.removeEventListener('click', element.__vueClickOutside__);
    element.__vueClickOutside__ = null;
  }
});

Implementation

By registering the policy above in your code, an example usage will look like this:

Vue.directive('click-out', {
  bind: function(element, binding, node) {
    // verifica se o parametro da diretiva é diferente de um objeto do tipo function.
    if (typeof binding.value !== 'function') {
      var component = node.context.name;
      var text = '[Vue-click-out:] a expressão informada deve ser uma função';
      if (component) {
        text += ' Component: ' + component;
      };
      console.warn(text);
    };
    // cria o evento e atribui ao elemento
    var bubble = binding.modifiers.bubble;
    var handler = function(evt) {
      if (bubble || (!element.contains(evt.target) && element !== evt.target)) {
        binding.value(evt);
      };
    };
    element.__vueClickOutside__ = handler;
    // adiciona o evento que trata os cliques fora do component
    document.addEventListener('click', handler);
  },

  unbind: function(element) {
    // remove o evento que trata cliques fora do componente
    document.removeEventListener('click', element.__vueClickOutside__);
    element.__vueClickOutside__ = null;
  }
});

var navList = new Vue({
  el: '#app',
  data: function() {
    return {
      visible: false
    }
  },
  methods: {
    show: function() {
      this.visible = !this.visible;
    },
    hide: function() {
      this.visible = false;
    }
  }
})
.dropdown {
  display: none;
}

.dropdown.active {
  display: block;
}
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script><divid="app">
  <ul>
    <li>Home</li>
    <li @click="show" v-click-out="hide">
      Products
      <ul class="dropdown" :class="{active: visible}">
        <li>Product 1</li>
        <li>Product 2</li>
      </ul>
    </li>
    <li>About us</li>
  </ul>
</div>

Basically you have v-bind or : to class checking if visible is true ( true ) and assigning class .active if this is the case. Also the v-on or @ for the click event, assigning by show , true or false method (the opposite of the current value in the property) to visible and directive co_de %, by assigning v-click-out , hide to false .

Test

...<li @click="show" v-click-out="visible = true">...

Inthecaseofthisdirectiveitisonlypossibletoinformamethodforexecution,howeveryoucanadaptittoreceivea VueJS expression.

Information

More about visible (directives) in VueJS 2.x here .

    
10.07.2017 / 19:00