工作上需要给 element plus 的 tree 组件添加右键菜单,参考网上的示例简单实现了一个,开箱即用,简单方便。代码和使用示例如下:
<template>
<div
v-show="visible"
:style="{
left: + 'px',
top: + 'px',
display: visible ? 'block' : 'none',
}"
class="context-menu"
>
<div
v-for="(item, i) in menuItems"
:key="i"
class="menu-item"
@click="(rightClickItem)"
>
{{ }}
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
interface Props {
menuItems: ContextMenuItem[];
}
export interface ContextMenuItem {
name: string;
icon?: string;
action: (rightClickItem: any) => void;
}
const props = defineProps<Props>();
const visible = ref(false);
const rightClickItem = ref(null);
const position = ref({
top: 0,
left: 0,
});
const openMenu = (e: MouseEvent, item: any) => {
let menuCount = ;
let windowHeight = ;
= true;
= (, windowHeight - 40 - menuCount * 32);
= ;
= item;
};
const closeMenu = () => {
= false;
};
watch(visible, () => {
if () {
("click", closeMenu);
} else {
("click", closeMenu);
}
});
defineExpose({ openMenu, closeMenu });
</script>
<style scoped lang="less">
.context-menu {
margin: 0;
background: #fff;
z-index: 2;
position: absolute;
list-style-type: none;
padding: 4px;
border-radius: 4px;
font-size: 12px;
font-weight: 400;
color: #333;
box-shadow: 2px 2px 2px 2px rgba(0, 0, 0, 0.3);
.menu-item {
padding: 0 15px;
height: 32px;
line-height: 32px;
color: rgb(29, 33, 41);
cursor: pointer;
}
.menu-item:hover {
background: var(--el-color-primary-light-9);
border-radius: 4px;
}
}
</style>
使用示例:
<template>
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick">
<template #default="{ node }">
<span @="contextMenuRef!.openMenu($event, node)">
{{ }}
</span>
</template>
</el-tree>
<context-menu :menu-items="menuItems" ref="contextMenuRef" />
</template>
<script lang="ts" setup>
import { ref } from "vue";
import ContextMenu from "../components/contextMenu/";
import { ContextMenuItem } from "../components/contextMenu/";
interface Tree {
label: string;
children?: Tree[];
}
const contextMenuRef = ref<InstanceType<typeof ContextMenu>>();
const menuItems = ref<ContextMenuItem[]>([
{
name: "新增",
action: (item: any) => {
(item, "新增");
},
},
{
name: "修改",
action: (item: any) => {
(item, "修改");
},
},
{
name: "删除",
action: (item: any) => {
(item, "删除");
},
},
]);
const handleNodeClick = (data: Tree) => {
(data);
};
const data: Tree[] = [
{
label: "Level one 1",
children: [
{
label: "Level two 1-1",
children: [
{
label: "Level three 1-1-1",
},
],
},
],
},
{
label: "Level one 2",
children: [
{
label: "Level two 2-1",
children: [
{
label: "Level three 2-1-1",
},
],
},
{
label: "Level two 2-2",
children: [
{
label: "Level three 2-2-1",
},
],
},
],
},
{
label: "Level one 3",
children: [
{
label: "Level two 3-1",
children: [
{
label: "Level three 3-1-1",
},
],
},
{
label: "Level two 3-2",
children: [
{
label: "Level three 3-2-1",
},
],
},
],
},
];
const defaultProps = {
children: "children",
label: "label",
};
</script>
参考文章:vue3实现右键菜单