vue vxe-context-menu 通用右键菜单组件使用

在ERP或后天管理系统开发中,右键菜单是提升操作效率的常用交互方式。Vxe UI 提供的 vxe-context-menu 组件,让你可以轻松为任何元素绑定自定义右键菜单,并支持多级菜单、图标配置、禁用/显示控制等丰富功能。本文将从基础用法到高级配置,全面介绍该组件的使用技巧。

菜单配置

通过 options 配置菜单选项,通过 children 最多支持二级菜单

html 复制代码
<template>
  <div>
    <vxe-button @contextmenu="showMenuEvent">右键显示</vxe-button>
    <vxe-context-menu v-model="showMenu" v-bind="menuOptions" v-on="menuEvents"></vxe-context-menu>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import { VxeUI } from 'vxe-pc-ui'
const showMenu = ref(false)
const menuOptions = reactive({
  x: 0,
  y: 0,
  options: [
    [
      { code: '11', name: '新增' },
      { code: '22', name: '删除' },
      {
        code: '33',
        name: '审批',
        children: [
          { code: '44', name: '通过' },
          { code: '55', name: '不通过' }
        ]
      },
      { code: '66', name: '查看' }
    ],
    [
      {
        code: '111',
        name: '更多操作',
        children: [
          { code: '113', name: '编辑' },
          { code: '114', name: '取消' }
        ]
      },
      { code: '110', name: '驳回' }
    ]
  ]
})
const menuEvents = {
  optionClick({ option }) {
    VxeUI.modal.message({
      content: `点击了 ${option.code}`,
      status: 'success'
    })
  }
}
const showMenuEvent = ({ $event }) => {
  $event.preventDefault()
  $event.stopPropagation()
  menuOptions.x = $event.clientX
  menuOptions.y = $event.clientY
  showMenu.value = true
}
</script>
  • 每个菜单项支持以下属性:
属性 类型 说明
code string number
name string 菜单项显示文字
children Array 子菜单项(支持二级菜单)
prefixIcon string 前缀图标类名
suffixIcon string 后缀图标类名
prefixConfig object 前缀配置(支持文字或图标)
suffixConfig object 后缀配置(支持文字或图标)
disabled boolean 是否禁用
visible boolean 是否显示

前缀与后缀图标

通过 prefixIcon / suffixIcon 配置图标,或使用 prefixConfig / suffixConfig 配置自定义内容:

html 复制代码
<template>
  <div>
    <vxe-button @contextmenu="showMenuEvent">右键显示</vxe-button>
    <vxe-context-menu v-model="showMenu" v-bind="menuOptions"></vxe-context-menu>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
const showMenu = ref(false)
const menuOptions = reactive({
  x: 0,
  y: 0,
  options: [
    [
      { code: '11', name: '新增', prefixIcon: 'vxe-icon-add' },
      { code: '22', name: '删除', prefixIcon: 'vxe-icon-delete' },
      {
        code: '33',
        name: '审批',
        prefixIcon: 'vxe-icon-empty',
        children: [
          { code: '44', name: '通过', prefixConfig: { content: 'Ctrl+R' } },
          { code: '55', name: '不通过', prefixConfig: { content: 'Ctrl+X' } }
        ]
      },
      { code: '66', name: '查看', prefixIcon: 'vxe-icon-link' }
    ],
    [
      {
        code: '111',
        name: '更多操作',
        children: [
          { code: '113', name: '编辑', prefixConfig: { content: 'Ctrl+V' } },
          { code: '114', name: '取消', prefixConfig: { content: 'Ctrl+C' } }
        ]
      },
      { code: '110', name: '驳回', prefixIcon: 'vxe-icon-add' }
    ]
  ]
})
const showMenuEvent = ({ $event }) => {
  $event.preventDefault()
  $event.stopPropagation()
  menuOptions.x = $event.clientX
  menuOptions.y = $event.clientY
  showMenu.value = true
}
</script>

是否禁用

设置 disabled: true 可让菜单项不可点击,并显示灰色样式:

html 复制代码
<template>
  <div>
    <vxe-button @contextmenu="showMenuEvent">右键显示</vxe-button>
    <vxe-context-menu v-model="showMenu" v-bind="menuOptions" v-on="menuEvents"></vxe-context-menu>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import { VxeUI } from 'vxe-pc-ui'
const showMenu = ref(false)
const menuOptions = reactive({
  x: 0,
  y: 0,
  options: [
    [
      { code: '11', name: '新增(Ctrl+V)', disabled: false },
      { code: '22', name: '删除(Ctrl+T)', prefixIcon: 'vxe-icon-delete', disabled: true },
      {
        code: '33',
        name: '审批',
        disabled: false,
        children: [
          { code: '44', name: '通过', prefixIcon: 'vxe-icon-check', disabled: false },
          { code: '55', name: '不通过', prefixIcon: 'vxe-icon-close', disabled: false }
        ]
      },
      { code: '66', name: '查看(Ctrl+X)', prefixIcon: 'vxe-icon-link', disabled: true }
    ],
    [
      {
        code: '111',
        name: '更多操作',
        disabled: false,
        children: [
          { code: '113', name: '编辑(Ctrl+Y)', disabled: true },
          { code: '114', name: '取消(Ctrl+B)', disabled: false }
        ]
      },
      { code: '110', name: '驳回(Ctrl+Z)', disabled: true }
    ]
  ]
})
const menuEvents = {
  optionClick({ option }) {
    VxeUI.modal.message({
      content: `点击了 ${option.code}`,
      status: 'success'
    })
  }
}
const showMenuEvent = ({ $event }) => {
  $event.preventDefault()
  $event.stopPropagation()
  menuOptions.x = $event.clientX
  menuOptions.y = $event.clientY
  showMenu.value = true
}
</script>

是否显示

通过 visible 属性可以动态控制菜单项的显隐,适用于权限控制等场景:

html 复制代码
<template>
  <div>
    <vxe-button @contextmenu="showMenuEvent">右键显示</vxe-button>
    <vxe-context-menu v-model="showMenu" v-bind="menuOptions" v-on="menuEvents"></vxe-context-menu>
  </div>
</template>

<script setup>
import { reactive, ref } from 'vue'
import { VxeUI } from 'vxe-pc-ui'
const showMenu = ref(false)
const menuOptions = reactive({
  x: 0,
  y: 0,
  options: [
    [
      { code: '11', name: '新增(Ctrl+V)', visible: true },
      { code: '22', name: '删除(Ctrl+T)', prefixIcon: 'vxe-icon-delete', visible: false },
      {
        code: '33',
        name: '审批',
        visible: true,
        children: [
          { code: '44', name: '通过', prefixIcon: 'vxe-icon-check', visible: true },
          { code: '55', name: '不通过', prefixIcon: 'vxe-icon-close', visible: true }
        ]
      },
      { code: '66', name: '查看(Ctrl+X)', prefixIcon: 'vxe-icon-link', visible: false }
    ],
    [
      {
        code: '111',
        name: '更多操作',
        visible: true,
        children: [
          { code: '113', name: '编辑(Ctrl+Y)', visible: false },
          { code: '114', name: '取消(Ctrl+B)', visible: true }
        ]
      },
      { code: '110', name: '驳回(Ctrl+Z)', visible: false }
    ]
  ]
})
const menuEvents = {
  optionClick({ option }) {
    VxeUI.modal.message({
      content: `点击了 ${option.code}`,
      status: 'success'
    })
  }
}
const showMenuEvent = ({ $event }) => {
  $event.preventDefault()
  $event.stopPropagation()
  menuOptions.x = $event.clientX
  menuOptions.y = $event.clientY
  showMenu.value = true
}
</script>

全局调用

除了通过组件方式使用,Vxe UI 还提供了全局 API,方便在任意位置调用:

javascripy 复制代码
import { VxeUI } from 'vxe-pc-ui'

// 打开右键菜单(指定位置)
VxeUI.contextMenu.open({
  x: 100,
  y: 200,
  options: [
    [
      { code: '1', name: '选项一' },
      { code: '2', name: '选项二' }
    ]
  ]
})

// 基于鼠标事件打开(自动获取位置)
VxeUI.contextMenu.openByEvent(event, {
  options: [
    [
      { code: '1', name: '选项一' }
    ]
  ]
})

// 关闭右键菜单
VxeUI.contextMenu.close()

事件列表

事件名 参数 说明
optionClick { option, $event } 点击菜单项时触发
open { options } 菜单打开时触发
close --- 菜单关闭时触发
show --- 菜单显示时触发
hide --- 菜单隐藏时触发

无论是为表格、树形控件,还是任意 DOM 元素绑定右键菜单,vxe-context-menu 都能提供优雅的右键菜单解决方案。

https://vxeui.com

相关推荐
miss5 分钟前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
招风的黑耳8 分钟前
SpringBoot+Vue+MySQL 民宿在线预定平台 完整可运行版(源码+文档)
vue.js·spring boot·mysql
AiMan43 分钟前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真1 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment1 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan1 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么1 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
上海懒图科技1 小时前
工厂厂区电子地图定位导航:厂区人车精准定位,安全合规双保障
前端·arcgis·vue
西安小哥2 小时前
端侧跑大模型,真正的门槛不在参数量:一次 596 秒到 10 秒的压缩路径复盘
前端·人工智能
陈随易2 小时前
Cloudflare 出钱,Vite 团队挑人,44 个维护者分 30 万美元
前端·后端·程序员