我有一个定制的vue指令。
Vue.directive('click-outside', {
bind: function (el, binding, vnode) {
document.addEventListener(clickHandler, (event) => {
const clickedInsideDropdown = el.contains(event.target);
if (!clickedInsideDropdown && el.classList.contains(openClass)) {
vnode.context.$emit(binding.expression);
}
});
}
});然后使用下拉模板初始化它:
<template>
<div class="dropdown" :class="{ '-is-open': open }" v-click-outside="close">
<span @click="toggle">
<slot name="toggle"></slot>
</span>
<slot name="menu"></slot>
</div>
</template>支持逻辑也如预期的那样运作:
<script>
export default {
data: function () {
return {
open: false
}
},
methods: {
close: function () {
this.open = false;
console.log('close');
},
toggle: function () {
this.open = !this.open;
console.log('toggle');
}
}
}
</script>问题
当当前下拉_is打开且其中没有一个条目被单击时,该事件就会触发(控制台日志记录证实了这一点)。但是,由于某些原因,$emit没有触发close方法。
2.5.3发布于 2017-11-11 21:19:49
归功于我在论坛上回答了我的问题的Linus。只是不正确地理解事件的目的。
事件通常用于从子组件到父组件的通信,因此触发组件中的事件“关闭”将不会在该组件中运行该名称的方法。 如果您想要这样做,您必须实际注册该事件的侦听器:
created () {
this.$on('close', this.close /*the name of the method to call */)
}但是,在您的情况下,这并不是必要的。您已经将close方法传递给该指令,因此您可以直接运行它:
Vue.directive('click-outside', {
bind: function (el, binding, vnode) {
document.addEventListener(clickHandler, (event) => {
const clickedInsideDropdown = el.contains(event.target);
if (!clickedInsideDropdown && el.classList.contains(openClass)) {
binding.value()
// alternartively, you could also call the method directly on the instance, no need for an event:
vnode.context.[expression]()
// but that wouldn't really be elegant, agreed?
}
});
}
});https://stackoverflow.com/questions/47234598
复制相似问题