方案一
npm install vue-contextmenu
<span v-contextmenu:contextmenuRef @contextmenu="tabContextMenuClick(index)"></span>
<v-contextmenu ref="contextmenuRef">
<v-contextmenu-item @click="closeCurTag">关闭当前</v-contextmenu-item>
<v-contextmenu-item @click="closeRightTag">关闭右侧</v-contextmenu-item>
<v-contextmenu-item @click="closeOtherTag">关闭其他</v-contextmenu-item>
<v-contextmenu-item @click="closeAllTag">关闭所有</v-contextmenu-item>
</v-contextmenu>
ref名与指令参数统一,可自定义菜单和逻辑
methods:{
tabContextMenuClick(){}
}
方案二
1.封装RightMenu组件
<template>
<ul class="table-right-menu">
<li v-for="item in data.menuList" :key="item.btnName" class="table-right-menu-item" @click.stop="fnHandler(item)">
<div class="table-right-menu-item-btn">
<i :class="item.iconName" class="icon" />
<span>{{ item.btnName }}</span>
</div>
</li>
</ul>
</template>
<script>
export default {
name: "RightMenu",
props: {
data: {
type: Object,
default: () => {
return {
position: {
x: null,
y: null,
},
menuList: [
{
fnName: "",
params: {},
iconName: "",
btnName: "",
},
],
}
},
},
classIndex: {
type: Number,
default: 0,
},
},
watch: {
"data.position" (val) {
let x = val.x
let y = val.y
let innerWidth = window.innerWidth
let innerHeight = window.innerHeight
let menu = document.getElementsByClassName("table-right-menu")[this.classIndex]
menu.style.display = "block"
let menuHeight = this.data.menuList.length * 30
let menuWidth = 180
menu.style.top = (y + menuHeight > innerHeight ? innerHeight - menuHeight : y) + "px"
menu.style.left = (x + menuWidth > innerWidth ? innerWidth - menuWidth : x) + "px"
document.addEventListener("mouseup", this.hide, false)
},
},
methods: {
hide (e) {
if (e.button === 0) {
let menu = document.getElementsByClassName("table-right-menu")[this.classIndex]
menu.style.display = "none"
document.removeEventListener("mouseup", this.hide)
}
},
fnHandler (item) {
this.$emit(item.fnName, item.params)
},
},
};
</script>
<style lang='scss' scoped>
.table-right-menu {
color: #333;
background: #fff;
border-radius: 4px;
list-style-type: none;
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
font-size: 12px;
font-weight: 500;
box-sizing: border-box;
padding: 4px 0;
position: fixed;
z-index: 3000;
display: none;
.table-right-menu-item {
box-sizing: border-box;
padding: 6px 12px;
border-radius: 4px;
transition: all 0.36s;
cursor: pointer;
.table-right-menu-item-btn {
.icon {
margin-right: 4px;
}
}
}
.table-right-menu-item:hover {
background-color: #ebf5ff;
color: #6bacf2;
}
}
</style>
2.父组件使用
<el-table @row-contextmenu="rowContextMenu"></el-table>
<right-menu :data="rightMenuInfo" @deleteRow="deleteRow"></right-menu>
components: {
RightMenu: () => import('./RightMenu'),
},
methods:{
rowContextMenu (row, column, e) {
this.rightMenuInfo = {
position: {
x: e.clientX,
y: e.clientY,
},
menuList: [
{
fnName: "deleteRow",
params: { row, column, e },
iconName: "el-icon-delete",
btnName: "删除当前行",
},
],
}
e.preventDefault()
},
deleteRow(){}
}