参考代码:实现Vue3+Element-Plus(tree、table)右键菜单组件
这篇文章的代码确实能用,但是存在错误,修正后的代码:
<template><div style="text-align: right"><el-icon size="12" color="#999" style="cursor: pointer"><Plus /></el-icon></div><el-tree:data="catalogTreeData":props="{ label: 'label', children: 'children' }":expand-on-click-node="false"ref="deptTreeRef"node-key="id"highlight-currentdefault-expand-all@node-contextmenu="rightClick"/><div class="rightMenu" v-show="showMenu"><ul><li v-for="(menu, index) in menus" @click="menu.click" :key="index"><el-icon><component :is="menu.icon" /></el-icon><span style="margin-left: 10px">{{ menu.name }}</span></li></ul></div>
</template>
<script lang="ts" setup>
import { FolderAdd, Message, Plus, UserFilled } from '@element-plus/icons-vue'
import { markRaw } from 'vue'
const showMenu = ref(false)const menus = ref<{icon: anyname: stringclick: () => void}[]
>([])const catalogTreeData = [{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 rightClick = (event: MouseEvent, data: any, node: any, json: any) => {event.preventDefault()showMenu.value = false// 显示位置let menuPosition = document.querySelector('.rightMenu') as HTMLElementif (menuPosition) {menuPosition.style.left = event.clientX + 'px'menuPosition.style.top = event.clientY + 'px'}menus.value = [{icon: markRaw(FolderAdd), // 默认图标name: '新增子目录', // 默认名称click: () => {console.log('新增子目录')}},{icon: markRaw(Message),name: '编辑',click: () => {console.log('编辑')}},{icon: markRaw(UserFilled),name: '删除',click: () => {console.log('删除')}}]showMenu.value = truedocument.addEventListener('click', close)
}function close() {showMenu.value = false
}
</script>
<style scoped>
.rightMenu {position: fixed;z-index: 99999999;cursor: pointer;border: 1px solid #eee;box-shadow: 0 0.5em 1em 2px rgba(0, 0, 0, 0.1);border-radius: 6px;color: #606266;font-size: 14px;background: #fff;
}.rightMenu ul {list-style: none;margin: 0;padding: 0;border-radius: 6px;
}.rightMenu ul li {padding: 6px 10px;border-bottom: 1px solid #c8c9cc;box-sizing: border-box;display: flex;align-items: center;justify-content: flex-start;
}.rightMenu ul li:last-child {border: none;
}.rightMenu ul li:hover {transition: all 0.5s;background: #ebeef5;
}
.rightMenu ul li:hover {transition: all 0.5s;background: #ebeef5;
}.rightMenu ul li:first-child {border-radius: 6px 6px 0 0;
}
.rightMenu ul li:last-child {border-radius: 0 0 6px 6px;
}
</style>