javascript - clickoutside 指令防止其他点击事件在 vue 组件中触发
问题描述
我已经为关闭侧边栏实现了点击外部指令。指令工作正常,但侧栏的内容(任何点击事件都不会触发)。如何停止传播该事件?
这是我的 clickoutside.js
import Vue from 'vue';
const nodeList = [];
const ctx = '@@clickoutsideContext';
let startClick;
const counter = 0;
const isServer = Vue.prototype.$isServer;
/**
* added this on event function for direct dom manipulation
*/
const onEvent = (function() {
if (!isServer && document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
};
}
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent(`on${event}`, handler);
}
};
})();
!isServer &&
onEvent(document, 'mousedown', e => {
startClick = e;
});
!isServer &&
onEvent(document, 'mouseup', e => {
nodeList.forEach(node => node[ctx].documentHandler(e, startClick));
});
// setting up mouse events
function createDocumentHandler(el, binding, vnode) {
return function(mouseup = {}, mousedown = {}) {
if (
!vnode ||
!vnode.context ||
!mouseup.target ||
!mousedown.target ||
el.contains(mouseup.target) ||
el.contains(mousedown.target) ||
el === mouseup.target ||
(vnode.context.popperElm &&
(vnode.context.popperElm.contains(mouseup.target) ||
vnode.context.popperElm.contains(mousedown.target)))
)
return;
if (
binding.expression &&
el[ctx].methodName &&
vnode.context[el[ctx].methodName]
) {
vnode.context[el[ctx].methodName]();
} else {
el[ctx].bindingFn && el[ctx].bindingFn();
}
};
}
/**
* v-clickoutside
* @desc Only trigger when click outside
* @example
* ```vue
* <div v-element-clickoutside="handleClose">
* ```
*/
export default {
bind(el, binding, vnode) {
nodeList.push(el);
const id = counter + 1;
el[ctx] = {
id,
documentHandler: createDocumentHandler(el, binding, vnode),
methodName: binding.expression,
bindingFn: binding.value
};
},
update(el, binding, vnode) {
el[ctx].documentHandler = createDocumentHandler(el, binding, vnode);
el[ctx].methodName = binding.expression;
el[ctx].bindingFn = binding.value;
},
unbind(el) {
const len = nodeList.length;
for (let i = 0; i < len; i += 1) {
if (nodeList[i][ctx].id === el[ctx].id) {
nodeList.splice(i, 1);
break;
}
}
delete el[ctx];
}
};
这是我在组件模板中添加指令的地方
<v-main :style="{ paddingTop: '48px' }" >
<div v-clickoutside = "closeEvent">
<v-container fluid class="pa-0">
<keep-alive>
<router-view name="layout" />
</keep-alive>
<router-view />
</v-container>
</div>
<keep-alive>
<SideBar v-model="drawer" />
</keep-alive>
</v-main>
在此侧边栏中有多个按钮,但 onclick 不起作用,单击这些按钮时侧边栏会关闭。
解决方案
@mousedown 在 @click 事件之前运行,这就是您无法单击侧边栏内容的原因。我建议从官方文档https://vuejs.org/v2/guide/events.html中查看事件修饰符(特别是 .stop),或者确定要触发的适当事件。
推荐阅读
- php - PHP Excel 不导出超过 11000 行
- c# - ASP.NET Core 登录 2 个不同的文件
- c# - asp.net 在未经身份验证时获取会员用户的用户名(重置密码)
- css - IE11 中的粗体看起来与 chrome 中的粗体有很大不同 - 这可以补救吗?
- javascript - 将变量从函数传递到 if 语句
- python - 如何从另一个 .py 脚本中的 .py 脚本访问变量
- java - 编辑器窗口中的工件:错误的 Eclipse 配置或错误?
- r - 使用for循环对数据框中的列进行求和,创建新的数据框
- java - 尝试使用服务帐户凭据创建代码以将 JSON 发送到 GCP 时出错
- neo4j - 所有孩子的 Neo4j 循环