Appearance
ContextMenu 右键菜单
AuContextMenu 只负责菜单展示与交互,业务确认通过 beforeSelect 注入。
基础用法
下面的演示包含图标行、按钮组、二级菜单、禁用项、分隔线和危险操作。
配置式菜单
在演示区点击右键;删除动作会先进入 beforeSelect 注入的确认流程。
在这里点击右键菜单坐标来自鼠标事件,并自动限制在浏览器视口内
vue
<template>
<div>
<div class="context-menu-demo" @contextmenu.prevent="openMenu">
<AuIcon :icon="IconMenu2" :size="28" />
<strong>在这里点击右键</strong>
<span>菜单坐标来自鼠标事件,并自动限制在浏览器视口内</span>
</div>
<AuContextMenu
v-model="visible"
:items="menuSections"
:position="position"
:before-select="beforeSelect"
@select="handleSelect"
@cancel="handleCancel"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import {
AuContextMenu,
AuIcon,
AuMessage,
AuMessageBox,
IconCopy,
IconMenu2,
IconStar,
IconTrash,
} from 'aurora-plus';
const visible = ref(false);
const position = ref({ x: 0, y: 0 });
const menuSections = [
{
id: 'quick-actions',
type: 'icon-row',
ariaLabel: '快捷操作',
items: [
{ id: 'copy-link', label: '复制链接', icon: IconCopy },
{ id: 'favorite', label: '收藏项目', icon: IconStar },
],
},
{ id: 'separator-1', type: 'separator' },
{
id: 'main-actions',
type: 'button-group',
items: [
{ id: 'copy', label: '复制', icon: IconCopy, shortcut: 'Ctrl+C' },
{ id: 'favorite-menu', label: '收藏', icon: IconStar },
],
},
{
id: 'more',
type: 'submenu',
label: '更多操作',
items: [
{ id: 'rename', label: '重命名' },
{ id: 'archive', label: '归档项目' },
{ id: 'submenu-separator', kind: 'separator' },
{ id: 'disabled', label: '不可用操作', disabled: true },
],
},
{ id: 'separator-2', type: 'separator' },
{
id: 'delete-section',
type: 'button',
item: {
id: 'delete',
label: '删除',
icon: IconTrash,
danger: true,
confirmMessage: '确定删除这个示例项目吗?',
},
},
];
function openMenu(event) {
position.value = { x: event.clientX, y: event.clientY };
visible.value = true;
}
async function beforeSelect(item) {
if (!item.confirmMessage) return true;
return AuMessageBox.confirm({
title: '危险操作',
message: item.confirmMessage,
confirmButtonType: 'danger',
});
}
function handleSelect(item) {
AuMessage.success(`已执行:${item.label}`);
}
function handleCancel(item) {
AuMessage.info(`已取消:${item.label}`);
}
</script>
<style scoped>
.context-menu-demo {
display: flex;
align-items: center;
justify-content: center;
min-height: 220px;
border: 1px dashed var(--au-color-border);
border-radius: 10px;
color: var(--au-color-text-secondary);
background: var(--au-color-bg-soft);
flex-direction: column;
gap: 9px;
user-select: none;
}
.context-menu-demo strong {
color: var(--au-color-text-primary);
font-size: 15px;
}
.context-menu-demo span {
color: var(--au-color-text-secondary);
font-size: 12px;
}
</style>数据结构
items 接收 AuContextMenuSection[]。Section 决定布局,Section 内的 item 决定具体动作。
Section 类型
type | 使用字段 | 说明 |
|---|---|---|
button / item | item,也兼容直接写在 section 上 | 单个菜单项 |
button-group / group | items | 纵向普通菜单项组 |
icon-row | items、ariaLabel | 单行图标按钮 |
icon-grid | items、ariaLabel | 图标网格 |
submenu | id、label、items | 二级菜单;内部 item 可用 kind: 'separator' |
separator | — | 分隔线 |
MenuItem 字段
| 字段 | 说明 | 类型 |
|---|---|---|
id | 业务动作标识,建议必填且唯一 | string / number |
label | 展示文本及图标按钮提示 | string |
title | 原生 title,主要用于普通菜单项 | string |
icon | 图标组件 | Component |
shortcut | 右侧快捷键提示,仅展示、不监听键盘 | string |
danger | 是否使用危险色 | boolean |
disabled | 是否禁用 | boolean |
kind / type | 子菜单分隔项可设为 separator | string |
| 其他字段 | 原样保留并随事件返回,例如 confirmMessage | unknown |
ContextMenu API
Attributes
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
modelValue / v-model | 是否显示菜单 | boolean | true |
items | 菜单 Section 数据 | AuContextMenuSection[] | [] |
position | 视口坐标 | { x: number, y: number } | { x: 0, y: 0 } |
iconColor | 图标行统一颜色 | string | '' |
ariaLabel | 菜单无障碍名称 | string | 上下文菜单 |
beforeSelect | 选择前守卫;返回 false 取消动作 | (item) => boolean | Promise<boolean> | — |
hideOnSelect | 成功选择后是否关闭 | boolean | true |
closeOnClickOutside | 点击外部是否关闭 | boolean | true |
teleported | 是否传送到 appendTo | boolean | true |
appendTo | Teleport 目标 | string / HTMLElement | body |
zIndex | 菜单层级 | number | 2200 |
Events
| 事件名 | 说明 | 参数 |
|---|---|---|
update:modelValue | 内部关闭时更新绑定值 | (visible: boolean) |
select | 守卫通过后触发 | (item: AuContextMenuItem) |
action | select 的兼容事件,参数相同 | (item: AuContextMenuItem) |
cancel | beforeSelect 返回 false 时触发 | (item: AuContextMenuItem) |
close | 菜单关闭时触发 | (reason: string) |
关闭原因包括 api、select、outside 和 escape。
Exposes
| 属性或方法 | 说明 |
|---|---|
close(reason?) | 主动关闭菜单 |
updatePosition() | 根据最新坐标和菜单尺寸执行视口避让 |
menuRef | 菜单根元素引用 |
交互说明
菜单打开后会获得焦点。ArrowUp、ArrowDown、Home、End 可在可用按钮间移动,Escape 关闭菜单。组件只展示 shortcut,快捷键监听仍应由业务层实现。