1. 原生方法
1.1 完整代码
<template> <div class="home"> <!-- 在需要右键菜单的元素,绑定contextmenu事件 --> <div class="test" v-for="item in menus" :key="item" @contextmenu.prevent="openMenu($event,item)">{{item}}</div> <!-- 右键菜单部分 --> <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu"> <li @click="handleDelete">删除</li> <li @click="handleDownloadFile">下载</li> <li @click="handlePreviewFile">预览</li> </ul> </div> </template> <script> export default { data() { return { menus:[1,2,3], // 模拟数据 rightClickItem:'', visible: false, // 是否展示右键菜单 top:0, left:0, }; }, methods: { // 打开右键菜单 openMenu(e,item){ this.visible = true; this.top = e.pageY; this.left = e.pageX; this.rightClickItem = item; }, // 关闭右键菜单 closeMenu(){ this.visible = false; }, handleDelete(){}, handleDownloadFile(){}, handlePreviewFile(){}, }, watch: { // 监听 visible,来触发关闭右键菜单,调用关闭菜单的方法 visible(value) { if (value) { document.body.addEventListener('click', this.closeMenu) } else { document.body.removeEventListener('click', this.closeMenu) } } }, }; </script> <style lang="stylus" scoped> .home{ display: flex; justify-content: space-around; width: 100%; height: 600px; .test{ width: 80px; height: 60px; background-color pink; text-align:center; font-size:32px; color: green; } .contextmenu { margin: 0; background: #fff; z-index: 3000; position: absolute; list-style-type: none; padding: 5px 0; border-radius: 4px; font-size: 12px; font-weight: 400; color: #333; box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3); } .contextmenu li { margin: 0; padding: 7px 16px; cursor: pointer; } .contextmenu li:hover { background: #eee; } } </style>
1.2 效果
2. 使用插件 vue-context-menu
安装
npm install vue-contextmenu --save
引入
import VueContextMenu from 'vue-contextmenu' Vue.use(VueContextMenu)
2.1 普通列表菜单
2.1.1 完整代码
<template> <div id="app" @contextmenu="showMenu" style="width: 200px;height: 200px;margin-top: 20px;background: pink;"> <vue-context-menu :contextMenuData="contextMenuData" @deleteData="deleteData" @newAdd="newAdd"> </vue-context-menu> </div> </template> <script> export default { data() { return { // 菜单数据 contextMenuData: { menuName: 'demo', // 菜单显示的位置 axis: { x: null, y: null }, // 菜单选项 menulists: [ { fnHandler: 'deleteData', // 绑定事件 icoName: 'el-icon-delete', // 图标 (本文取自 element-ui) btnName: '保存' // 菜单名称 },{ fnHandler: 'newAdd', icoName: 'el-icon-plus', btnName: '新增' } ] } }; }, methods: { showMenu () { event.preventDefault() var x = event.clientX; var y = event.clientY; // 获取当前位置 this.contextMenuData.axis = { x, y } }, // 删除 deleteData () {}, // 新增 newAdd () {} }, watch: {}, }; </script>
2.1.2 效果
2.2 树型菜单
2.2.1 完整代码
<template> <div style="position: fixed; left: 0px; top: 0"> <div @contextmenu="showMenu(index)" style="width: 100px; height: 100px; margin-top: 20px; background: red" v-for="(n, index) in 2" :key="n" > <vue-context-menu :contextMenuData="contextMenuData" :transferIndex="transferIndex" @Handler1="Handler_A(index)" @Handler2="Handler_B(index)" @Handler3="Handler_C(index)" ></vue-context-menu> </div> </div> </template> <script> export default { name: "app", data() { return { transferIndex: null, contextMenuData: { menuName: "demo", axis: { x: null, y: null, }, menulists: [ { btnName: "选项1", icoName: "el-icon-s-tools", children: [ { icoName: "el-icon-download", btnName: "选项1-1", // 子菜单 children: [ { icoName: "el-icon-share", btnName: "选项1-1-1", children: [ { icoName: "el-icon-switch-button", fnHandler: "Handler1", btnName: "选项1-1-1", }, ], }, ], }, ], }, { btnName: "选项2", children: [ { fnHandler: "Handler2", btnName: "选项2-1", }, ], }, { btnName: "选项3", fnHandler: "Handler3", }, { btnName: "选项4", disabled: true, }, ], }, }; }, methods: { showMenu(index) { this.transferIndex = index; // 将索引转换到子组件 event.preventDefault(); var x = event.clientX; var y = event.clientY; this.contextMenuData.axis = { x,y }; }, Handler_A(index) { console.log(index, "选项 1-1-1 绑定事件执行"); }, Handler_B(index) { console.log(index, "选项 2-1 绑定事件执行"); }, Handler_C(index) { console.log(index, "选项 3 绑定事件执行"); }, }, }; </script> <style> * { margin: 0; padding: 0; } </style>
2.2.2 效果