index.vue
<script setup>
import { computed, unref } from 'vue';
const props = defineProps({
menuConfig: {
type: Array,
required: true
},
virtualRef: Function,
zIndex: {
type: Number,
default: 1000
}
})
const warpRef = ref()
const emit = defineEmits(['menu-click'])
const contextMenuArgs = ref()
const setWarpRef = (el) => {
warpRef.value = el
props.virtualRef(el)
}
const classNames = computed(() => {
return {
}
})
const init = (args) => {
contextMenuArgs.value = args
}
const handleClick = (menu) => {
warpRef.value.classList.remove('show')
emit('menu-click', {
menu,
...unref(contextMenuArgs)
})
}
defineExpose({
init
})
</script>
<template>
<Teleport to="body">
<div class="shadow-lg el-table--context-menu-wrapper" :ref="setWarpRef"
:style="{ zIndex: zIndex }">
<div class="w-32 contentBox">
<div class="box" v-for="(box, index1) in menuConfig" :key="index1">
<div class="itemBox" v-for="(itemBox, index2) in box" :key="index2" @click="handleClick(itemBox)">
{{ itemBox.name }}
</div>
</div>
</div>
</div>
</Teleport>
</template>
<style lang="scss" scoped>
.el-table--context-menu-wrapper {
position: absolute;
top: 0;
left: 0;
border-radius: 5px;
font-size: 12px;
// border: 1px solid #dadce0;
// box-shadow: 3px 3px 6px -2px rgba(223, 221, 221, 0.6);
padding: 5px 0px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: #fff;
display: none;
&.show {
display: block;
}
.contentBox {
.box {
border-bottom-width: 1px;
.itemBox {
padding: 0 25px;
cursor: pointer;
line-height: 30px;
&:hover {
background-color: #f5f7fa
}
}
}
.box:last-child {
border-bottom-width: 0;
}
}
}
</style>
hook.js
使用
<template>
<div class="app-container">
<el-table border :data="tableData" style="width: 100%" @cell-contextmenu="handleContextMenu">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
<ContextMenu
:menu-config="menuConfig"
@menu-click="contextMenuClickEvent"
:virtual-ref="contextMenuVirtualRef"
ref="contextMenuRef" />
</div>
</template>
<script setup>
import ContextMenu from "@/components/ContextMenu/index.vue";
import contextMenuHook from "@/components/ContextMenu/hook";
const { handleContextMenu, contextMenuVirtualRef, contextMenuRef } = contextMenuHook()
const menuConfig = ref([
[
{ code: 'copy', name: '复制', prefixIcon: 'vxe-icon-copy', className: 'my-copy-item' }
],
[
{ code: 'remove', name: '删除', prefixIcon: 'vxe-icon-delete-fill color-red' },
{
name: '筛选',
children: [
{ code: 'clearFilter', name: '清除筛选' },
{ code: 'filterSelect', name: '按所选单元格的值筛选' }
]
},
{
code: 'sort',
name: '排序',
prefixIcon: 'vxe-icon-sort color-blue',
children: [
{ code: 'clearSort', name: '清除排序' },
{ code: 'sortAsc', name: '升序', prefixIcon: 'vxe-icon-sort-alpha-asc color-orange' },
{ code: 'sortDesc', name: '倒序', prefixIcon: 'vxe-icon-sort-alpha-desc color-orange' }
]
},
{ code: 'print', name: '打印', disabled: true }
]
])
const contextMenuClickEvent = ({ menu, row, column }) => {
console.log(999, menu.code, column);
}
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
</script>
<style lang="scss" scoped></style>