我正在使用此帖子中的自定义click-outside
指令:
这是我的元素:
<div class="datepicker panel panel-default" v-click-outside="close">
自定义指令:
module.exports = {
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);
}
};
它有效,据我所知,绑定发生在元素的渲染上。因为我只希望在我的日期选择器出现时注册click事件,所以我用v-if
包装它。
问题在于,当我使用按钮切换日期选择器上v-if
的显示时,指令中的close
方法会立即触发。
似乎bind
内的事件在元素被显示之前发生,因此它立即关闭,根本不显示任何内容。
这看起来很奇怪,按钮负责显示datepicker,我希望在datepicker渲染时发生绑定。不是在同一时间或之前。
现在它似乎甚至在元素完全渲染之前就已经发生了。这会导致我的显示按钮导致v-click-outside事件。
造成这种情况的原因是什么?
修改
制作一个Jsfiddle来演示这个问题(打开控制台):
答案 0 :(得分:1)
听起来绝对符合逻辑。这是发生的事情:
show
方法,因为在按钮上有@click="show"
visible
属性更改为true。
由于点击事件
el
(带指令的div)与event.target
(按钮)不同由于if-else就在
hide
)
hide
函数被调用,visible
属性设置为false,因此组件被隐藏!
与示例相比,您在此处缺少的是从另一个目标(案例中的按钮)中打开日期选择器。这意味着默认情况下, ARE 在元素外部单击以显示它。
您有两个选项 - 一个是检查日期选择器的当前状态 - 添加另一个属性(justOpened
),在true
内将其设置为show
,当您检查是否它是否在外部点击,如果属性为true
,则将其设置为false
并返回。这样你就可以“跳过”这样的一件事。
如果您只是这样做,则不需要所有这些:
<button type="button" @click.stop="show">Show datepicker</button>
此.stop
修饰符实际上会在本机点击事件上调用stopImmediatePropagation()
,因此当您单击此按钮时,您的指令将不会被调用。它就像一个魅力,但要注意,如果你打开日期选择器,然后再次单击相同的按钮,日期选择器将不会被隐藏(因为它不会知道你已经点击了外面)!
希望有所帮助:)