Dropdown Menu 下拉菜单
用于下拉菜单场景的 MoriUI 组件。
导入
import { DropdownMenu, DropdownMenuArrow, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuItemIndicator, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from 'moriui'
示例
概览
账户与设置的下拉菜单。
<script setup lang="ts">
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger
} from 'moriui'
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
打开
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>我的账户</DropdownMenuLabel>
<DropdownMenuItem>个人资料<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut></DropdownMenuItem>
<DropdownMenuItem>账单<DropdownMenuShortcut>⌘B</DropdownMenuShortcut></DropdownMenuItem>
<DropdownMenuItem>设置<DropdownMenuShortcut>⌘S</DropdownMenuShortcut></DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>团队</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>邀请用户</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuItem>邮件</DropdownMenuItem>
<DropdownMenuItem>消息</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>更多…</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuSub>
<DropdownMenuItem>新建团队<DropdownMenuShortcut>⌘+T</DropdownMenuShortcut></DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>GitHub</DropdownMenuItem>
<DropdownMenuItem>支持</DropdownMenuItem>
<DropdownMenuItem disabled>
API
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>退出登录<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut></DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</template>
基础
最小化的菜单内容。
<script setup lang="ts">
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from 'moriui'
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
操作
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-48">
<DropdownMenuGroup>
<DropdownMenuItem>编辑</DropdownMenuItem>
<DropdownMenuItem>复制</DropdownMenuItem>
<DropdownMenuItem>删除</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>分享</DropdownMenuItem>
<DropdownMenuItem>导出</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</template>
图标
为菜单项添加图标。
<script setup lang="ts">
import { Copy, Download, Edit, Share2, Trash2 } from '@lucide/vue'
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from 'moriui'
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
操作
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-48">
<DropdownMenuGroup>
<DropdownMenuItem>
<Edit class="size-4" />
编辑
</DropdownMenuItem>
<DropdownMenuItem>
<Copy class="size-4" />
复制
</DropdownMenuItem>
<DropdownMenuItem>
<Trash2 class="size-4" />
删除
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<Share2 class="size-4" />
分享
</DropdownMenuItem>
<DropdownMenuItem>
<Download class="size-4" />
下载
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</template>
复选项
CheckboxItem 支持多选状态。
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Button,
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger
} from 'moriui'
const showStatusBar = shallowRef(true)
const showActivity = shallowRef(false)
const showNotifications = shallowRef(true)
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
显示选项
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-56">
<DropdownMenuLabel>界面设置</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem v-model="showStatusBar">
状态栏
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem v-model="showActivity">
活动面板
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem v-model="showNotifications">
通知提醒
</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
</template>
图标复选项
带图标的复选菜单项。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Activity, Bell, Eye } from '@lucide/vue'
import {
Button,
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger
} from 'moriui'
const showStatusBar = shallowRef(true)
const showActivity = shallowRef(false)
const showNotifications = shallowRef(true)
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
显示选项
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-56">
<DropdownMenuLabel>界面设置</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem v-model="showStatusBar">
<Eye class="size-4" />
状态栏
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem v-model="showActivity">
<Activity class="size-4" />
活动面板
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem v-model="showNotifications">
<Bell class="size-4" />
通知提醒
</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
</template>
单选项
RadioItem 与 RadioGroup 管理唯一选择。
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from 'moriui'
const density = shallowRef('comfortable')
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
界面密度
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-48">
<DropdownMenuLabel>密度设置</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuRadioGroup v-model="density">
<DropdownMenuRadioItem value="default">
默认
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="comfortable">
舒适
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="compact">
紧凑
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
</template>
图标单选项
带图标的单选菜单项。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Monitor, Moon, Sun } from '@lucide/vue'
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItemIndicator,
DropdownMenuLabel,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from 'moriui'
const theme = shallowRef('system')
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
主题
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-48">
<DropdownMenuLabel>选择主题</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuRadioGroup v-model="theme">
<DropdownMenuRadioItem value="light">
<DropdownMenuItemIndicator />
<Sun class="size-4" />
浅色
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="dark">
<DropdownMenuItemIndicator />
<Moon class="size-4" />
深色
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="system">
<DropdownMenuItemIndicator />
<Monitor class="size-4" />
跟随系统
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
</template>
快捷键
Shortcut 展示菜单项的键位提示。
<script setup lang="ts">
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuTrigger
} from 'moriui'
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
快捷键
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>编辑</DropdownMenuLabel>
<DropdownMenuItem>
撤销
<DropdownMenuShortcut>⌘Z</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
重做
<DropdownMenuShortcut>⇧⌘Z</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
剪切
<DropdownMenuShortcut>⌘X</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
复制
<DropdownMenuShortcut>⌘C</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
粘贴
<DropdownMenuShortcut>⌘V</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel>导航</DropdownMenuLabel>
<DropdownMenuItem>
查找
<DropdownMenuShortcut>⌘F</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
全部保存
<DropdownMenuShortcut>⌘⇧S</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</template>
子菜单
Sub、SubTrigger 与 SubContent 构建多级菜单。
<script setup lang="ts">
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger
} from 'moriui'
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
更多
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-48">
<DropdownMenuItem>新建文件</DropdownMenuItem>
<DropdownMenuItem>打开文件</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuSub>
<DropdownMenuSubTrigger>导入</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuItem>从文件导入</DropdownMenuItem>
<DropdownMenuItem>从剪贴板导入</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>从云端导入</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuItem>Google Drive</DropdownMenuItem>
<DropdownMenuItem>Dropbox</DropdownMenuItem>
<DropdownMenuItem>iCloud</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuSub>
</DropdownMenuSubContent>
</DropdownMenuSub>
<DropdownMenuSub>
<DropdownMenuSubTrigger>导出</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuItem>导出为 PDF</DropdownMenuItem>
<DropdownMenuItem>导出为 PNG</DropdownMenuItem>
<DropdownMenuItem>导出为 SVG</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuSub>
</DropdownMenuContent>
</DropdownMenu>
</template>
破坏性
使用样式区分危险操作。
<script setup lang="ts">
import { AlertTriangle, Ban, Trash2, UserX } from '@lucide/vue'
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from 'moriui'
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
危险操作
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-56">
<DropdownMenuGroup>
<DropdownMenuItem class="text-destructive focus:text-destructive">
<Trash2 class="size-4" />
删除项目
</DropdownMenuItem>
<DropdownMenuItem class="text-destructive focus:text-destructive">
<UserX class="size-4" />
移除成员
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem class="text-destructive focus:text-destructive">
<Ban class="size-4" />
禁用账户
</DropdownMenuItem>
<DropdownMenuItem class="text-destructive focus:text-destructive">
<AlertTriangle class="size-4" />
报告问题
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</template>
头像
在 Trigger 中使用头像。
<script setup lang="ts">
import { HelpCircle, LogOut, Settings, User } from '@lucide/vue'
import {
Avatar,
AvatarFallback,
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuTrigger
} from 'moriui'
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button
variant="ghost"
size="icon"
class="rounded-full"
aria-label="打开用户菜单"
>
<Avatar>
<AvatarFallback>张三</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-56" align="end">
<DropdownMenuGroup>
<DropdownMenuLabel>张三</DropdownMenuLabel>
<DropdownMenuItem>
<User class="size-4" />
个人资料
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<Settings class="size-4" />
设置
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<HelpCircle class="size-4" />
帮助
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<LogOut class="size-4" />
退出登录
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</template>
复杂
组合多种菜单项类型的场景。
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Bell,
CreditCard,
HelpCircle,
LogOut,
Palette,
Settings,
User
} from '@lucide/vue'
import {
Avatar,
AvatarFallback,
Button,
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger
} from 'moriui'
const notifications = shallowRef(true)
const theme = shallowRef('system')
</script>
<template>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline" size="icon" class="rounded-full">
<Avatar class="size-7">
<AvatarFallback>张三</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-64">
<DropdownMenuGroup>
<DropdownMenuLabel>张三</DropdownMenuLabel>
<DropdownMenuItem>
<User class="size-4" />
个人资料
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard class="size-4" />
账单
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<Settings class="size-4" />
设置
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem v-model="notifications">
<Bell class="size-4" />
通知提醒
</DropdownMenuCheckboxItem>
<DropdownMenuSeparator />
<DropdownMenuRadioGroup v-model="theme">
<DropdownMenuLabel>主题</DropdownMenuLabel>
<DropdownMenuRadioItem value="light">
<Palette class="size-4" />
浅色
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="dark">
<Palette class="size-4" />
深色
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="system">
<Palette class="size-4" />
跟随系统
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
<DropdownMenuSeparator />
<DropdownMenuSub>
<DropdownMenuSubTrigger>更多</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuItem>
<HelpCircle class="size-4" />
帮助中心
</DropdownMenuItem>
<DropdownMenuItem>
<LogOut class="size-4" />
退出登录
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuSub>
</DropdownMenuContent>
</DropdownMenu>
</template>
RTL
菜单在 RTL 上下文中的定位。
<script setup lang="ts">
import {
Button,
DirectionProvider,
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuTrigger
} from 'moriui'
</script>
<template>
<DirectionProvider dir="rtl">
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
فتح القائمة
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>حسابي</DropdownMenuLabel>
<DropdownMenuItem>
الملف الشخصي
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
الإعدادات
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
تسجيل الخروج
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</DirectionProvider>
</template>
使用说明
组合方式
DropdownMenu 由 Trigger、Content、Item、Separator、Group、Label 与 Sub 组成,CheckboxItem 和 RadioItem 提供选择能力。
子菜单
Sub、SubTrigger 与 SubContent 构建多级嵌套菜单。
复选与单选
CheckboxItem 和 RadioItem 使用 Indicator 表达选中状态;RadioGroup 管理单项选择。
RTL
dir 控制弹层定位与方向键行为。
变体
DropdownMenuContent 的 side、align 来自 Reka Popper 定位,无公开视觉变体。
可访问性
DropdownMenu 复用 Reka UI 的 menu ARIA、方向键导航、Enter/Space 选择与 Escape 关闭。Trigger 应有 aria-haspopup;Content 内需要为 Label 等提供合适的语义。
API 参考
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
DropdownMenu v-model:open | boolean | undefined | 菜单的受控打开状态。 |
DropdownMenu defaultOpen | boolean | false | 非受控初始打开状态。 |
DropdownMenuTrigger as / asChild | string | Component / boolean | 'button' / false | 触发器的元素组合能力。 |
DropdownMenuContent side / align | PopperContentProps | 'bottom' / 'start' | 弹层方向与对齐。 |
DropdownMenuItem disabled | boolean | false | 禁用菜单项。 |
DropdownMenuCheckboxItem v-model | boolean | 'indeterminate' | undefined | 复选框的选中状态。 |
DropdownMenuRadioItem value | AcceptableValue | — | 必填的单选项值。 |
DropdownMenuRadioGroup v-model | AcceptableValue | undefined | 单选组当前值。 |
DropdownMenuSeparator class | HTMLAttributes["class"] | undefined | 合并到分隔线的调用方类。 |
DropdownMenuLabel class | HTMLAttributes["class"] | undefined | 合并到标签的调用方类。 |
DropdownMenuSub v-model:open | boolean | undefined | 子菜单的受控打开状态。 |
DropdownMenuSubTrigger disabled | boolean | false | 禁用子菜单触发器。 |
DropdownMenuShortcut class | HTMLAttributes["class"] | undefined | 合并到快捷键标签的调用方类。 |