一个现代化、可访问(ARIA)、可扩展的右键菜单组件,支持:
- 多级子菜单(hover 弹出)
- 复选项(checkbox)与分隔线(divider)
- 禁用态、快捷键提示、图标占位
- 自动/手动关闭(autoClose 开关)
- 边界防溢出定位、点击外部与 ESC 关闭
目录结构与代码基于 Vite + Vue 3 + TypeScript。
npm install
npm run dev
打开浏览器访问终端显示的本地地址即可预览。
- 作为库安装与使用
npm install @foreverempty_/vue-rightclick-menu
在项目中:
import { ContextMenu, registerComponentMenu } from '@foreverempty_/vue-rightclick-menu'
import '@foreverempty_/vue-rightclick-menu/style/context-menu.css'
- 在任意元素上注册菜单:
import { registerComponentMenu } from '@/util/registerComponentMenu'
import type { MenuItem } from '@/types/menu'
const items: MenuItem[] = [
{ id: 'copy', label: '复制', onClick: () => console.log('copy') },
{ id: 'paste', label: '粘贴', disabled: true },
{ id: 'div1', type: 'divider' },
{
id: 'showLine',
type: 'checkbox',
label: '显示行号',
checked: true,
onClick: (c) => console.log('checked', c),
},
{
id: 'view',
type: 'multile',
label: '视图',
children: [
{ id: 'zoomIn', label: '放大', onClick: () => console.log('zoom in') },
{ id: 'zoomOut', label: '缩小', onClick: () => console.log('zoom out') },
],
},
]
// 选择器批量注册示例
document.querySelectorAll<HTMLElement>('.test').forEach((el) => {
registerComponentMenu(el, items)
})
- 在根组件挂载一次菜单容器:
<ContextMenu :autoClose="true" />
当 autoClose
设为 false
时,点击菜单项不会自动关闭(仍可通过外部点击或 ESC 关闭)。
-
组件:
ContextMenu
autoClose?: boolean
:是否点击后自动关闭(默认 true)。
-
工具函数:
registerComponentMenu(el: HTMLElement, items: MenuItem[]): () => void
- 绑定右键事件并显示菜单;返回解注册函数用于移除监听。
-
类型:
MenuItem
(见下)
export type MenuItem =
| {
id: string | number
type?: 'normal'
label?: string
disabled?: boolean
icon?: string
shortcut?: string
onClick?: () => void
}
| {
id: string | number
type: 'checkbox'
label?: string
disabled?: boolean
icon?: string
shortcut?: string
checked?: boolean
onClick?: (checked: boolean) => void
}
| { id: string | number; type: 'divider' }
| {
id: string | number
type: 'multile'
label?: string
disabled?: boolean
icon?: string
shortcut?: string
children: MenuItem[]
}
使用 type: 'multile'
并提供 children: MenuItem[]
即可递归渲染。悬停父项会在右侧弹出子菜单。
- 容器使用
role="menu"
、子项使用role="menuitem"
/role="separator"
- 支持 ESC 关闭与点击外部关闭
你可以通过以下方式自定义右键菜单的样式:
组件默认样式位于 styles/context-menu.css
。你可以在你的项目中引入自己的 CSS 文件,并覆盖默认样式。例如:
/* 覆盖菜单背景色和字体颜色 */
.context-menu {
background: #222;
color: #fff;
}
/* 自定义菜单项悬停效果 */
.context-menu-item:hover {
background: #444;
color: #ffd700;
}
或参考 exampless/coustomStyle.css
。
确保你的自定义样式在默认样式之后加载。
如果你在 App.vue
或其他组件中使用 <style scoped>
,可以通过深度选择器覆盖子组件样式:
<style scoped>
/* ::v-deep 用于穿透子组件样式 */
::v-deep .context-menu {
border-radius: 8px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}
</style>
你也可以直接修改 styles/context-menu.css
文件,来满足你的个性化需求。
MIT