vue - 选项卡右击下拉框
在 element-ui 环境下,给选项卡添加右击事件,是相当麻烦的一件事情,
主要是麻烦,很多东西都需要注意,并没有太多难点。
注意项
el-tabs 的右击事件
事件的名称是 contextmenu.prevent.native,这个很快就能找到,需要注意的是:
选项卡整个头部都能触发右击事件,需要过滤出哪些事件是由选项卡触发的。
右击下拉框实现方案
只需要在界面隐藏一个下拉框,点击的时候,获取点击位置信息,将下拉框显示在该位置即可。
获取 e.target 的 clientX/clientY 属性,动态控制面板的 left/top 即可,
这种方式,也可以用在很多吸附弹窗上,还需要注意的是 z-index,避免沉在界面底部。
关闭下拉框
弹出下拉框之后,需要有一个对应的关闭事件,不论点击哪里,都要触发关闭事件。
这时候,要给 windows 对象,添加 mousedown 事件。
mousedown 事件冲突
添加 mousedown 事件之后,就会发现下拉框中的点击事件,是触发不了的;
因此,要通过 e.target 的属性,判断点击事件是否属于下拉框。
代码样例
下面只包含核心代码,可能有一些错误,照着意思改改。
<template>
<div style="">
<div v-show="dropdown_visible" :style="style" class="sea-dropdown-menu">
<p class="el-dropdown-menu__item" id="sea-tabs-close-current">关闭当前</p>
<p class="el-dropdown-menu__item" id="sea-tabs-close-left">关闭左边</p>
<p class="el-dropdown-menu__item" id="sea-tabs-close-right">关闭右边</p>
<hr/>
<p class="el-dropdown-menu__item" id="sea-tabs-close-other">关闭其他</p>
<p class="el-dropdown-menu__item" id="sea-tabs-close-all">关闭所有</p>
</div>
<el-tabs type="card" v-model="current_tabs_name"
@contextmenu.prevent.native="onTabRightClick">
<el-tab-pane label="用户管理" name="first">用户管理</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
/**
* 中央选项卡
*/
export default {
name: "center-tabs"
, data() {
return {
// 右击菜单可见性
dropdown_visible: false
// 触发下拉事件的选项卡 name
, dropdown_name: undefined
// 右击菜单位置
, left: undefined
// 右击菜单位置
, top: undefined
}
},
computed: {
/**
* 样式
*/
style: function () {
return "left: " + this.left + "px; top: " + this.top + "px;";
}
},
mounted() {
// 落下鼠标时,需要移除展开的右击菜单
window.addEventListener('mousedown', this.onWindowsMousedown);
},
methods: {
/**
* 关闭选项卡右击菜单
*
* 下拉列表的点击事件与当前事件冲突,在这个事件里触发点击事件
*/
onWindowsMousedown: function (e) {
let clazz = e.target.getAttribute('class');
let id = e.target.getAttribute('id');
if (clazz === 'el-dropdown-menu__item') {
// todo sth.
}
this.dropdown_visible = false;
this.dropdown_name = undefined;
},
/**
* 右击事件 - 打开选项卡右击菜单
*
* name 记录在标签的 aria-controls 字段,格式为 "pane-[name]"
*
* @param e 事件
*/
onTabRightClick(e) {
if (e.target.id !== '') {
let controls = e.target.getAttribute('aria-controls');
if (controls.length > 5) {
this.dropdown_name = controls.substring(5);
console.log(this.dropdown_name);
this.dropdown_visible = true;
this.left = e.clientX;
this.top = e.clientY;
} else {
// 不合常理的右击事件
console.error('unknown aria-controls: ' + controls);
}
}
}
}
, destroyed() {
// 移除鼠标落下的侦听事件
this.dropdown_visible = false;
window.removeEventListener('mousedown', this.onWindowsMousedown);
}
}
</script>
<style scoped>
.sea-dropdown-menu {
position: fixed;
width: 150px;
background-color: #fff;
z-index: 1024;
border-radius: 3px;
-webkit-box-shadow: 1px 2px 10px #ccc;
box-shadow: 1px 2px 10px #ccc;
}
</style>
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!