title, description
| title |
description |
| Dropdown 下拉菜单 |
点击 / 悬停 / 右键触发的操作列表,支持子菜单与键盘导航 |
Dropdown 下拉菜单
Dropdown 把一组操作收进一个菜单,用于行内操作(编辑/复制/删除)、账号菜单与右键菜单。
何时使用
- 操作多于 2 个、或含危险操作需要分组时,收进菜单比并排按钮更清晰;
- 表格行、树节点、卡片上承载右侧的「更多操作」;
- 右键上下文菜单(
trigger="contextmenu");
- 只有一个操作时不要用菜单,直接放按钮。
数据源写法
items 是最常用的写法,点击后通过 click 事件回传 { key, item }。
声明式写法
也可以把 G3DropdownItem 写在插槽里:它不渲染任何 DOM,只作为数据载体被 Dropdown 收集,因此键盘导航、高亮、子菜单这些能力与 items 写法完全一致。使用声明式写法时建议用 #trigger 显式指定触发器,避免触发器跟菜单项混在默认插槽里。
触发方式
菜单项类型
| 项配置 |
说明 |
{ key, label } |
普通项,点击回传 key |
{ icon } |
前置图标(组件或 VNode) |
{ shortcut } |
右侧快捷键提示文字(仅展示,不绑定按键) |
{ disabled } |
禁用项:不可点、键盘导航跳过 |
{ danger } |
危险项:红色文字 |
{ divider: true } |
分隔线 |
{ type: 'label', label } |
分组标签 |
{ children: [...] } |
子菜单,hover 展开(right-start 弹出) |
{ onClick: (item) => void } |
项自带回调,先于全局 click 事件执行 |
富头部与自定义菜单
#header 用于账号卡片之类的头部(不参与键盘导航);#menu 是完全自定义菜单结构的逃生舱。
键盘操作
菜单打开后焦点会进入菜单容器,因此可以直接用键盘:
| 按键 |
行为 |
↑ / ↓ |
移动高亮(跳过分隔线、分组标签与禁用项,循环) |
Home / End |
跳到首 / 末项 |
Enter |
选中高亮项并关闭菜单(有子菜单的父项只高亮,不选中) |
Esc |
关闭菜单(由 Popover 处理) |
API
Props
| 名称 |
类型 |
默认值 |
说明 |
items |
DropdownItemData[] |
— |
菜单项数组;不传时从默认插槽收集 G3DropdownItem,否则回退到 #menu |
open |
boolean |
— |
受控打开状态;不传即非受控 |
defaultOpen |
boolean |
false |
非受控时的初始状态 |
trigger |
'click' | 'hover' | 'contextmenu' |
'click' |
触发方式 |
placement |
Placement |
'bottom-start' |
菜单方位 |
disabled |
boolean |
false |
禁用 |
mouseEnterDelay |
number |
100 |
hover 打开延迟(ms) |
mouseLeaveDelay |
number |
200 |
hover 关闭延迟(ms)。有子菜单时适当调大 |
offset |
number |
4 |
与触发器的间距(px) |
unwrapped |
boolean |
true |
零包裹模式,触发器不额外包 <span> |
Events
| 名称 |
参数 |
说明 |
click |
({ key, item }) |
选中某个菜单项(不含分隔线 / 分组标签) |
update:open |
(open: boolean) |
打开状态变化 |
openChange |
(open: boolean) |
同上,语义别名 |
Slots
| 名称 |
参数 |
说明 |
default |
— |
触发器(未传 #trigger 时);或一组 G3DropdownItem |
trigger |
— |
显式指定触发器(推荐) |
header |
— |
菜单顶部富内容(不参与键盘导航) |
menu |
{ close: () => void } |
完全自定义菜单结构(无 items 与 G3DropdownItem 时生效) |
Props(G3DropdownItem)
| 名称 |
类型 |
默认值 |
说明 |
itemKey |
string | number |
— |
标识,点击时回传 |
label |
string |
'' |
菜单文本 |
icon |
Component |
— |
前置图标 |
danger |
boolean |
false |
危险项 |
disabled |
boolean |
false |
禁用项 |
divider |
boolean |
false |
渲染为分隔线(其余属性忽略) |
onClick |
(item) => void |
— |
项自带回调 |
类型定义
样式变量
| 变量 |
默认值 |
说明 |
--g3-dropdown-min-width |
180px |
菜单最小宽度 |
--g3-dropdown-max-height |
256px |
菜单最大高度(超出滚动) |
--g3-dropdown-item-padding-y / -x |
5px / 8px |
菜单项内边距 |
--g3-dropdown-item-radius |
4px |
菜单项圆角 |
--g3-dropdown-divider-margin |
4px 0 |
分隔线外边距 |
实现说明
- 三种数据源统一成一份
items 数组:声明式的 G3DropdownItem 由 Dropdown 在渲染时收集(读取 vnode.props),随后与 items 走完全相同的渲染与键盘逻辑,因此不会出现「声明式写法少了某个能力」的问题;
- 菜单容器是可聚焦的(
tabindex="-1"),打开后主动 focus(),键盘事件因此能被菜单自身接收,不需要全局监听;
- 子菜单是嵌套的 Popover(
trigger="hover"、placement="right-start"),递归渲染 items;子菜单内部 interactive=false,不参与主菜单的高亮联动;
- 打开时把 z-index 打到
popup 档,关闭回收;右键触发时浮层对齐鼠标位置;
- 菜单项高亮用
activeIndex 单值驱动,鼠标移入与键盘移动共用它,因此「键盘移动后鼠标移入」不会出现双高亮。