Skip to content

Menu 菜单 ​

独立的菜单列表,支持选中态与键盘导航。

基础用法 ​

基础用法

默认选中 ​

默认选中(value 回显)

禁用项 ​

禁用项

多级子菜单 ​

带 children 的菜单项显示展开箭头(›),点击或悬停展开子菜单,子菜单缩进展示;键盘 ArrowRight 进入、ArrowLeft 返回。

多级子菜单

尚未选择

水平导航 ​

mode="horizontal" 时菜单项横排,呈顶部导航条样式;一级子菜单向下浮出,二级及以上仍向右浮出。

水平导航(顶部导航条样式)

尚未选择

收起态 ​

collapsed(vertical / inline 生效,horizontal 不适用)将菜单收窄为只显示图标;vertical 模式悬停或点击图标项时子菜单向右浮出(子菜单内仍为完整菜单),inline 模式不浮出——子菜单仍就地展开(点击展开,悬停不展开)。

收起态(只显示图标)

尚未选择

分组 ​

type: "group" 的菜单项渲染为带组标题的分区(组标题小字、次要色、不可点),组内子项平铺在同一层,可继续混入子菜单与分隔线。

分组

带图标 ​

icon 使用 @oas-ui/icons 的图标名(内置图标名),以内联 SVG 渲染在文字左侧。

带图标

图标颜色(iconColor) ​

iconColor 字段显式固定图标颜色(优先于选中/禁用态默认色),支持任意 CSS 色值或 token;缺省 currentColor 随文字色。子元素声明式通道用 icon-color 属性。

图标颜色(iconColor / icon-color)

下载删除无 icon-color

分隔线 ​

type: "divider" 渲染一条细分隔线,不可点、不参与键盘导航。

分隔线

子元素声明式通道 ​

除 items JSON 外,可用 <oas-menu-item> / <oas-menu-group> / <oas-menu-divider> 子元素声明式书写(items 属性显式设置时优先,未设置时解析子元素收敛到同一渲染路径)。默认插槽文本为 label,属性对齐 items 字段:value / disabled / loading / icon / kind / danger / href / target / rel;<oas-menu-item> 内直接嵌套子元素即递归为子菜单,<oas-menu-group> 的 label 属性为组标题(value 可作 radio 组 id),组内子元素平铺同层。子元素增删、属性与文本变化会自动重渲染(MutationObserver)。

子元素声明式(分组 / 分隔线 / 嵌套 / checkbox / danger / href)

首页组件文档编辑 复制剪切显示网格线自动换行删除尚未选择

动态增删(MutationObserver 自动刷新)

追加一项首页设置

前置媒体(slot="leading") ​

菜单项支持前置媒体插槽:在 <oas-menu-item> 内放 <template slot="leading"> 或带 slot="leading" 的直接子元素,内容渲染在 label 前、优先于 icon 图标(同时给时 icon 不渲染);loading 加载态时 spinner 替换前置媒体位,收起态(collapsed)下媒体位与图标一致收敛(保留可见、间距归零——隐藏会让条目成为可 hover 的空白块)。适合头像、色块等任意富前置内容(items JSON 通道不支持——仅子元素声明式通道可用)。

头像前置媒体(avatar 例)

林晓雨陈以宁赵启铭退出登录

暗色菜单 ​

theme="dark" 使菜单局部使用暗色 token(深背景 + 浅文字),独立于全局主题;不设置时跟随全局主题。

暗色菜单

选择事件 ​

选择事件

尚未选择

多选(checkbox) ​

kind: "checkbox" 的叶子项渲染为方块勾选框(role="menuitemcheckbox",与 radio 的 ✓ 区分);多选勾选集以 JSON 数组形态写入 value,点击某项后 oas-select 的 detail 携带 checked(本次点击后的勾选态)。

多选(checkbox)

尚未勾选

危险操作项 ​

danger: true 使用红色语义(--oas-color-danger),用于删除、退出登录等危险操作;hover / 键盘高亮时红底加深。

危险操作项(danger)

尚未选择

链接项(href) ​

href 使菜单项渲染为 <a>(锚点语义:支持中键 / 右键新窗口,SEO 友好),target / rel 原样透传;点击仍会派发 oas-select 并写入选中态。示例链接用 target="_blank" 新开标签页,避免离开文档页。

链接项(href)

尚未选择

长菜单滚动 ​

max-height 限定菜单可视高度(纯数字自动补 px),超出部分在菜单内部滚动,适合长列表。

长菜单滚动(max-height)

字符定位(typeahead) ​

菜单聚焦后直接输入字符,即跳转到 label 匹配的项(连续字符缓冲,500ms 无输入自动重置;前缀匹配优先,无前缀则包含匹配)。示例标签带英文便于按键触发:按 c 跳到 Copy,继续按 u(组合 cu)跳到 Cut。

字符定位(typeahead)

菜单已聚焦,直接按键试试(如 c → Copy、cu → Cut)

inline 侧边导航 ​

mode="inline" 时子菜单就地展开(不浮出),是侧边导航的主流形态;展开 / 收起带高度过渡动画,支持多级嵌套。

inline 就地展开

受控展开 ​

expanded(JSON 数组)为受控属性:外部设置 / 更新它即可指定展开的子菜单集合;每次展开 / 收起派发 oas-expand-change(detail: { expanded, value, isExpanded }),受控场景下宿主据此把状态写回 expanded。

expanded 受控展开

展开「工作台」展开「消息中心」全部收起尚未操作

选中不收起 ​

浮出形态(vertical / horizontal)默认选中叶子项即收起展开的子菜单(展开态是临时的);close-on-select="false" 可保持展开,适合在浮层里连续选多项。mode="inline" 侧边导航默认不收(用户需看到所在分区),close-on-select="true" 可改为收起。kind="checkbox" 项的勾选切换永不收起。close-on-select 为布尔属性:存在即真(含 close-on-select="" 空值),仅显式 "false" 关闭——未设置时才按上述形态缺省(inline 不收 / 浮出收)。

选中不收起(close-on-select)

vertical + close-on-select="false":点叶子后子菜单保持展开

尚未选择

inline + close-on-select="true":点叶子后收起父级子菜单

尚未选择

手风琴 ​

accordion(配合 mode="inline")使同级子菜单互斥:展开一个自动收起同级的其他展开项。

手风琴互斥(inline + accordion)

水平溢出收纳 ​

mode="horizontal" 下容器宽度不足时,超宽的菜单项自动收进末尾「···」子菜单,导航条不换行、不截断。

水平溢出收纳

悬停展开子菜单 ​

open-on-hover 让 vertical / inline 模式的父项支持 hover 展开:悬停约 150ms 后展开、移出约 300ms 后收起(宽限期内移回取消收起);点击路径不变(仍可点击展开/收起)。mode="horizontal" 顶部导航与 collapsed 收起态的 flyout 本就是即时 hover 浮出,不受该属性影响。

open-on-hover(vertical 悬停延迟展开)

vertical:悬停「编辑」~150ms 展开,移出~300ms 收起

inline:悬停同样延迟展开(多开并存),点击仍可切换

整单禁用 ​

disabled 禁用整个菜单:点击 / 悬停 / 键盘全部拦截(href 项同时阻断原生跳转),宿主文字走禁用色(不叠 opacity)并同步 aria-disabled;移除属性即恢复交互。

整单禁用

纯动作菜单(selectable=false) ​

selectable="false" 关闭整单选中态语义:全部叶子项按动作项渲染(menuitem、无勾选标记、无 aria-checked),点击只派发 oas-select、不写回 value——适合「点了就走」的纯命令菜单(等价于把每个叶子项写成 kind: "action")。

纯动作菜单(无勾选态,不写回 value)

选中不收起(persistent) ​

persistent 让选中后浮出子菜单不自动收起(close-on-select 族的正向开关,显式时优先于 close-on-select):适合需要连续选择、选中后停留在当前位置的场景;value 照常写回。

persistent:选中后子菜单保持展开

可搜索(searchable) ​

searchable 在菜单顶部渲染过滤输入框,键入实时过滤可见项(浮出与 inline 形态都生效):命中嵌套子项时保留其祖先并自动展开命中路径,无匹配时显示空文案(复用 i18n 空态);Escape 清空搜索,ArrowDown 把焦点移入菜单。

可搜索(浮出 + inline)

浮出形态:在输入框键入「窗」过滤出「窗口布局」

尚未选择

inline 形态:键入「统计」就地过滤并展开命中路径

快捷键标注(shortcut) ​

菜单项 shortcut 字段(items JSON)或 <oas-menu-item shortcut="…"> 属性在行右端渲染 kbd 快捷键标注,与 menubar 的 shortcut 视觉契约一致。

快捷键标注(shortcut)

撤销重做粘贴

API ​

oas-menu ​

属性 ​

属性说明类型默认值
accordion手风琴互斥(inline 模式同级只展开一个子菜单)boolean—
close-on-select选中叶子项后是否收起展开的子菜单。缺省分形态:inline 侧边导航不收、浮出形态收;checkbox 项勾选切换永不收起string—
collapsed收起态(vertical / inline 生效,horizontal 不适用):只显示图标,子菜单向右浮出boolean—
disabled整单禁用:点击/悬停/键盘全拦截,降饱和 + aria-disabledboolean—
expanded受控展开项集合(JSON 数组字符串,inline 模式哪些子菜单展开);非受控时内部管理string—
items菜单项 JSON(支持 disabled / loading 禁点、icon、children 子菜单)MenuItem[] | null[]
max-height长菜单最大高度,超出内部滚动(数字补 px)string—
mode布局模式:vertical(默认)纵向菜单 / horizontal 顶部导航条 / inline 侧边导航(子菜单就地展开、带高度过渡)——
open-on-hoververtical/inline 父项 hover 延迟展开(约 150ms)/移出延迟收起(约 300ms),点击路径不变;horizontal 与 collapsed flyout 不受影响boolean—
persistent选中后不自动收起浮出子菜单(优先于 close-on-select)string—
searchable菜单顶部过滤输入框:键入实时过滤可见项(命中嵌套子项保留祖先并自动展开,Esc 清空)boolean—
selectable"false" 时纯动作菜单:叶子无勾选态、点击不写回 value(detail kind=action)stringtrue
theme局部主题:dark 使用暗色 token(独立于全局主题)——
value当前选中值。纯字符串时全局单选(无组场景,兼容旧用法);JSON 对象字符串(如 {"sort":"name","view":"list"})时按组 id 作用域独立记录——type:"group" 项的 value 作组 id,组内点选只更新该组string—

事件 ​

事件说明
oas-expand-change子菜单展开状态变化,detail: { expanded: string[], value, isExpanded }(受控/非受控都派发)
oas-select选择某项,detail: { value, kind? }。kind 仅动作项(kind: "action")出现,值为 "action";radio 项 detail.kind 不出现

CSS 变量 ​

CSS 变量默认值
--oas-menu-max-heightnone

oas-menu-item ​

属性 ​

属性说明类型默认值
danger破坏性项:红色语义(删除/退出等危险操作)——
disabled禁用该项——
href链接地址:有 href 时渲染为原生 <a>(真实跳转 + 照常派发 oas-select)——
icon前置图标(@oas-ui/icons 内置图标名)——
icon-color图标颜色:显式固定该色(优先于选中/禁用态默认色);缺省 currentColor 随文字色——
kind叶子项语义:radio(默认,可勾选)/ action(动作项,无勾选态、不写回 value)/ checkbox(多选勾选,value 数组勾选集)——
loading加载中:渲染 spinner、禁点,由数据驱动恢复——
rel链接 rel(配合 href)——
shortcut行右端快捷键标注(kbd 视觉,对齐 menubar shortcut 契约)——
target链接 target(配合 href)——
value选中值(子元素声明式通道的数据载体字段)——

插槽 ​

名称说明
默认菜单项 label 内容(默认插槽文本);直接子元素 <oas-menu-item>/<oas-menu-group>/<oas-menu-divider> 递归为子菜单 children
template[slot="leading"]前置媒体模板(或直接子元素加 slot="leading"):头像/色块等任意前置内容,渲染在 label 前、优先于 icon 图标;loading 态由 spinner 替换;仅子元素声明式通道可用(items JSON 不支持)

oas-menu-group ​

属性 ​

属性说明类型默认值
label分组标题(组标题小字、次要色、不可点)——
valueradio 组 id(组内点选只更新该组选中值)——

插槽 ​

名称说明
默认组内菜单项:子元素 <oas-menu-item>/<oas-menu-group>/<oas-menu-divider> 平铺同层

oas-menu-divider ​

插槽 ​

名称说明
默认分隔线数据载体(无属性,宿主解析为 type: "divider")

MenuItem 字段:

字段说明类型
label菜单项文字string
value选中值string
type菜单项类型:item(默认)/ group(分组标题)/ divider(分隔线)string
kind叶子项语义:radio(默认,可勾选)/ action(动作项,无勾选态、点击不写回 value)string
icon图标名(registerIcon() 自定义或 @oas-ui/icons 内置图标名)string
iconColor图标颜色(可选):显式固定该色,优先于选中/禁用态默认色;缺省 currentColor 随文字色string
disabled禁用该项boolean
children子菜单项数组,结构与父项一致(可继续嵌套)MenuItem[]

children 为可选子菜单项数组;有 children 的项点击/悬停展开子菜单,选中态只落在叶子项。group 的 children 平铺展示在同一层,组标题不可点、不参与键盘导航;divider 不可点、不参与键盘导航。

键盘导航:方向键移动(自动跳过组标题与分隔线)、Enter 选择(含子菜单的项 Enter/ArrowRight 进入)、Home / End 跳转、ArrowLeft 返回父级;role="menu" + menuitemradio(子菜单父项为 menuitem),选中项显示对勾。

基于 MIT OR Apache-2.0 双许可发布