我正在努力进行事件传播。如果没有保存数据,任务是防止单击其他任何内容。因此,左div包含选项树。单击项目后,将显示右侧div中的设置。我想警告用户,当他尝试在设置div之外单击时,数据没有保存。
代码如下:
<div class="row">
<div class="col-sm-6">
<tree
:data="treeData">
.. some tree data
</tree>
</div>
<div class="col-sm-6">
<div class="treeOptionEdit" v-if="showEditBox" v-click-outside.stop="checkIfSaved">
... setting input fields
vue-outside-events
包用于检测div以外的点击。工作正常。问题是此代码不执行任何操作:
checkIfSaved : function (event, el)
{
event.stopPropagation();
event.preventDefault();
},
无论如何,点击都会传播到父级。如果我将事件@click
放给了父级,则会触发所有点击。
停止传播只能从父母到孩子吗?
答案 0 :(得分:2)
我不熟悉v-click-outside
的实现,但是“外部点击”事件通常是通过在document / body元素上使用事件委托来实现的,因此到那时该事件已经传播并且无法传播停止了。
这是个小例子:
Vue.directive('click-outside', {
bind(el, { value }) {
el._handler = e => {
if (!el.contains(e.target)) {
value(e);
}
};
document.addEventListener('click', el._handler);
},
unbind(el) {
document.removeEventListener('click', el._handler);
},
});
new Vue({
el: '#app',
methods: {
onClick(e, color) {
alert(`Clicked the ${color} box.`);
},
onClickOutside(e, color) {
e.stopPropagation();
alert(`Clicked outside of ${color} box.`);
},
},
});
.box { padding: 20px; }
.red { background-color: red; }
.yellow { background-color: yellow; }
.blue { background-color: blue; }
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
<div id="app">
<div class="box red" @click="onClick($event, 'red')">
<div class="box yellow" @click="onClick($event, 'yellow')">
<div class="box blue" @click="onClick($event, 'blue')" v-click-outside="e => onClickOutside(e, 'blue')">
</div>
</div>
</div>
</div>
click-outside
指令已将事件侦听器附加到该文档元素)上后,将调用click-outside
处理程序。此时调用stopPropagation()
不会执行任何操作,因为该事件已经冒出来了。我不相信.stop
修饰符在您的示例中会执行任何操作,因为v-click-outside
不支持该修饰符({.stop
仅受v-on
; {{ 1}}需要支持它。
因此,要解决您的问题,您需要更改事件的顺序:v-click-outside
必须先处理v-click-outside
。
您可以通过使用以下事件捕获来更改@click
实现来实现此目的:
v-click-outside
Vue.directive('click-outside', {
bind(el, { value }) {
el._handler = e => {
if (!el.contains(e.target)) {
value(e);
}
};
// *** Using capturing ***
document.addEventListener('click', el._handler, { capture: true });
},
unbind(el) {
document.removeEventListener('click', el._handler, { capture: true });
},
});
new Vue({
el: '#app',
methods: {
onClick(e, color) {
alert(`Clicked the ${color} box.`);
},
onClickOutside(e, color) {
e.stopPropagation();
alert(`Clicked outside of ${color} box.`);
},
},
});
.box { padding: 20px; }
.red { background-color: red; }
.yellow { background-color: yellow; }
.blue { background-color: blue; }
为什么不向vue-outside-events提交拉取请求以支持此功能?