Skip to content

Dropdown 下拉菜单

点击或悬停触发的操作菜单。支持子菜单与键盘导航。

基础用法

最近选择:(尚未选择)
vue
<script setup>
const options = [
  { value: 'edit', label: '编辑' },
  { value: 'copy', label: '复制' },
  { value: 'delete', label: '删除', danger: true, divided: true }
]
</script>

<template>
  <SrDropdown :options="options" @select="onSelect">
    <SrButton>操作</SrButton>
  </SrDropdown>
</template>

触发器由默认插槽提供——组件不预设外观,放按钮、放图标、放一段文字都行。

选项字段

ts
interface SrDropdownOption {
  value: string | number
  label: string
  disabled?: boolean
  danger?: boolean      // 红色,用于删除这类破坏性操作
  divided?: boolean     // 上方加一条分隔线
  shortcut?: string     // 右侧的快捷键提示
  children?: SrDropdownOption[]  // 子菜单
}

dangerdivided两个独立的视觉信号

  • danger 用颜色强调危险性
  • divided 用分隔线表示分组(不只是"最后一个")。

删除项通常两个都用——颜色提醒"危险",分隔线把它和常规操作隔开, 减少"手滑点到"的概率。

子菜单

children 支持一层子菜单,方向自动适应——右侧空间不够时会向左展开。

vue
const options = [
  {
    value: 'export',
    label: '导出为',
    children: [
      { value: 'export-png', label: 'PNG' },
      { value: 'export-svg', label: 'SVG' }
    ]
  }
]

子菜单方向为什么必须自适应

靠近窗口右边缘时,向右展开会被裁掉。固定方向的话, 用户永远看不到那一列——而且他也不知道有东西被裁掉了。

组件会在展开前测量可用空间,选择左或右。

触发方式

vue
<SrDropdown :options="options" trigger="click" />
<SrDropdown :options="options" trigger="hover" />

触屏设备上的 hover 触发

触摸屏没有真正的悬停——hover 触发会退化成"点一下打开、 再点一下关闭",与 click 行为一致但缺少明确的视觉反馈。

触屏为主的场景建议用 click。若必须用 hover, 在 @media (hover: hover) 外保留点击兜底。

键盘导航

按键作用
↓ / ↑在选项间移动
展开子菜单
收起子菜单
Enter选中
Esc关闭并归还焦点到触发器
Home / End跳到首项 / 末项

禁用项会被跳过——焦点不会停在不可选的项上。

对齐方式

vue
<SrDropdown placement="bottom-start" />
<SrDropdown placement="bottom-end" />

菜单同样会自动校正视口边缘:靠近底部时向上展开。

选中后是否关闭

closeOnSelect 默认 true。多选式菜单(点了不关、可以连续操作) 可以设为 false

vue
<SrDropdown :options="options" :close-on-select="false" />

Props

名称类型默认值说明
optionsSrDropdownOption[][]菜单项
trigger'click' | 'hover''click'触发方式
placement'bottom-start' | 'bottom-end''bottom-start'对齐方式
disabledbooleanfalse是否禁用
closeOnSelectbooleantrue选中后是否关闭

插槽

名称说明
default触发器内容

事件

事件参数说明
select(option)选中某一项
visible-changeboolean显隐变化

无障碍

  • 触发器带 aria-haspopup="menu"aria-expanded
  • 菜单容器 role="menu",每项 role="menuitem"
  • danger不能只靠颜色区分——颜色是视觉提示, 语义应由文案承担(「删除」这个词本身已说明危险)
  • 关闭后焦点归还触发器等,与 Modal 的四要素一致(详见 Modal

自用组件库 · 源码分发 · 不发布 npm