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 .