SelectMenu
简洁、易用、高度可定制化的菜单解决方案
项目状态
版本更新内容请访问 Changelog
如果您的项目正在使用 vue 2.x 版本生态,请使用 v-selectmenu 2.x 版本
安装
将 v-selectmenu
组件安装到项目中
npm i v-selectmenu
yarn add v-selectmenu
pnpm add v-selectmenu
组件集
v-selectmenu
提供的组件
- SelectMenuDropdown 菜单主容器
- SelectMenuTrigger 组件内置的打开菜单的触发按钮
- SelectMenuBody 菜单内容的主容器
- SelectMenuSection 菜单片断容器
- SelectMenuRow 使内容水平对齐的布局容器
- SelectMenuColumn 使内容垂直对齐的布局容器
- SelectMenuHeader 菜单主标题栏
- SelectMenuSubHeader 菜单子标题栏
- SelectMenuDivider 分隔线
- SelectMenuGroup 菜单分组容器
- SelectMenuGroupItem 菜单分组项
- SelectMenuChildLevel 子菜单主容器
- SelectMenuSearch 内容输入模块
- SelectMenuItem 菜单项
- SelectMenuCheckboxGroup 多项选择容器
- SelectMenuCheckboxItem 多项选择项目
- SelectMenuRadioGroup 单项选择容器
- SelectMenuRadioItem 单项选择项目
实例
基础应用
设置一个菜单列表,并通过 action
事件统一接收菜单项发出的指令
菜单项选择事件响应数据
<SelectMenuDropdown>
<template #trigger>
<SelectMenuTrigger />
</template>
<SelectMenuBody @action="handleAction">
<SelectMenuItem action="item1">Item 1</SelectMenuItem>
<SelectMenuItem action="item2">Item 2</SelectMenuItem>
<SelectMenuItem action="item3">Item 3</SelectMenuItem>
</SelectMenuBody>
</SelectMenuDropdown>
import {
SelectMenuDropdown,
SelectMenuTrigger,
SelectMenuBody,
SelectMenuHeader,
SelectMenuItem
} from 'v-selectmenu'
function handleAction (action) {
console.log(action)
}
不应用下拉层
仅使用菜单,不通过下拉层展示
<SelectMenuBody class="border rounded-4 shadow-sm">
<SelectMenuHeader>Menu without dropdown</SelectMenuHeader>
<SelectMenuItem>Item 1</SelectMenuItem>
<SelectMenuItem>Item 2</SelectMenuItem>
<SelectMenuItem>Item 3</SelectMenuItem>
</SelectMenuBody>
菜单项
菜单项可通过 prepend
、default
与 append
等插槽设置前置、后置与菜单项主体内容
<SelectMenuBody>
<SelectMenuHeader>Menu item slots</SelectMenuHeader>
<SelectMenuDivider />
<SelectMenuItem>
<template #prepend>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bell b-svg-icon" viewBox="0 0 16 16">
<path d="M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2M8 1.918l-.797.161A4 4 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4 4 0 0 0-3.203-3.92zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5 5 0 0 1 13 6c0 .88.32 4.2 1.22 6"/>
</svg>
</template>
<template #append>
<span class="badge rounded-pill text-bg-danger">23</span>
</template>
Notifications
</SelectMenuItem>
<SelectMenuItem>Helps</SelectMenuItem>
<SelectMenuItem>Settings</SelectMenuItem>
</SelectMenuBody>
该内容结构设置同样应用于以下组件
- SelectMenuHeader
- SelectMenuSubHeader
- SelectMenuRadioItem
- SelectMenuCheckboxItem
块容器
块容器 SelectMenuSection
用于包裹菜单项类型的组件,可通过自定义样式设置该区块的高度或其他样式
这里通过设置 max-height
样式管理块容器高度,使区块内容超出后出现滚动条
<SelectMenuBody>
<SelectMenuSubHeader>Section 1</SelectMenuSubHeader>
<SelectMenuSection style="max-height: 170px;">
<SelectMenuItem>Item 1</SelectMenuItem>
<SelectMenuItem>Item 2</SelectMenuItem>
<SelectMenuItem>Item 3</SelectMenuItem>
...
</SelectMenuSection>
<SelectMenuSubHeader>Section 2</SelectMenuSubHeader>
<SelectMenuSection>
<SelectMenuItem>Item 1</SelectMenuItem>
<SelectMenuItem>Item 2</SelectMenuItem>
<SelectMenuItem>Item 3</SelectMenuItem>
</SelectMenuSection>
</SelectMenuBody>
关闭菜单的方式
在默认情况下,菜单项点击后,会自动关闭下拉菜单,如果需要保持菜单打开状态,则需要设置 hideOnItemClick
属性为 false
<SelectMenuBody :hideOnItemClick="false">
<SelectMenuItem action="item1">Item 1</SelectMenuItem>
<SelectMenuItem action="item2">Item 2</SelectMenuItem>
<SelectMenuItem action="item3">Item 3</SelectMenuItem>
</SelectMenuBody>
分隔线
分隔线组件,可以设置为横向或纵向
<SelectMenuBody>
<SelectMenuHeader>Menu divider</SelectMenuHeader>
<!-- horizontal divider -->
<SelectMenuDivider />
<SelectMenuRow>
<SelectMenuColumn>
<SelectMenuItem>Item 1</SelectMenuItem>
<SelectMenuItem>Item 2</SelectMenuItem>
<SelectMenuItem>Item 3</SelectMenuItem>
</SelectMenuColumn>
<!-- vertical divider -->
<SelectMenuDivider horizontal={false} />
<SelectMenuColumn>
<SelectMenuItem>Item 4</SelectMenuItem>
<SelectMenuItem>Item 5</SelectMenuItem>
<SelectMenuItem>Item 6</SelectMenuItem>
</SelectMenuColumn>
</SelectMenuRow>
</SelectMenuBody>
下拉层
下拉菜单的 SelectMenuDropdown
组件提供了状态与操作函数,可通过作用域插槽输出以及组件所提供的工具函数 useSelectMenuDropdown
获得
interface SelectMenuDropdownUtilities {
/**
* Dropdown 打开的状态
*/
visible?: Ref<boolean>
/**
* Dropdown 禁用状态
*/
disabled?: Ref<boolean>
/**
* 关闭菜单
*/
closeDropdown?: () => void
/**
* 自动调整打开的菜单位置
*/
adjustDropdown?: () => void
}
作用域插槽
SelectMenuDropdown
组件对 trigger
与 default
插槽均输出数据状态与操作函数,方便用户定制菜单内容与触发对象
<SelectMenuDropdown>
<template #trigger={ visible, disabled, closeDropdown, adjustDropdown }>
...
</template>
<template #default={ visible, disabled, closeDropdown, adjustDropdown }>
<div>
<div>Dropdown visible: {{ visible }}</div>
<div>Dropdown disabled: {{ disabled }}</div>
<button type="button" @click="closeDropdown">Close</button>
<button type="button" @click="adjustDropdown">Adjust</button>
</div>
</template>
</SelectMenuDropdown>
工具函数
当菜单的内容是一个用户自定义组件时,可以通过 useSelectMenuDropdown
函数获得菜单的状态与操作函数
<SelectMenuDropdown>
<template #trigger>
<SelectMenuTrigger />
</template>
<CustomDropdownContent />
</SelectMenuDropdown>
import {
SelectMenuDropdown,
SelectMenuTrigger
} from 'v-selectmenu'
import CustomDropdownContent from './CustomDropdownContent.vue'
<template>
<div>
<div>Dropdown visible: {{ visible }}</div>
<div>Dropdown disabled: {{ disabled }}</div>
<button
type="button"
@click="closeDropdown"
>Close dropdown</button>
<button
type="button"
@click="adjustDropdown"
>Adjust dropdown</button>
</div>
</template>
<script setup>
import { useSelectMenuDropdown } from 'v-selectmenu'
const {
visible,
disabled,
closeDropdown,
adjustDropdown
} = useSelectMenuDropdown()
</script>
内置触发按钮
v-selectmenu
内置了 SelectMenuTrigger
组件,用于触发菜单的打开与关闭,如果该按钮不满足需求,可通过 SelectMenuDropdown
的 trigger
插槽自定义触发对象
下拉层属性与事件
v-selectmenu
的下拉层基于 v-dropdown 实现,因此可以在 SelectMenuDropdown
组件上直接使用 v-dropdown
的属性与事件
这里设置了 trigger
属性为 hover
,下拉菜单的打开方式为鼠标悬停而不是默认的点击
<SelectMenuDropdown
trigger="hover"
@visible-change="visibleChange"
>
...
</SelectMenuDropdown>
Props
SelectMenuBody
的 Props
interface MenuBodyProps {
/**
* 指定当前菜单中所有 `SelectMenuItem` 点击后是否关闭菜单
* @default true
*/
hideOnItemClick?: boolean
}
SelectMenuItem
的 Props
interface MenuItemProps {
/**
* 菜单项选择后触发的指令,在 `SelectMenuBody` 的 action 事件中统一接收
*/
action?: string
/**
* @default false
*/
disabled?: boolean
}
SelectMenuDivider
的 Props
interface MenuDividerProps {
/**
* 横向分隔线,设置为 false 时为竖向分隔线
* @default true
*/
horizontal?: boolean
}
事件
SelectMenuBody
的事件
// 响应菜单项选择后,获得该项的 action 值的事件
action: (action: string) => void
插槽
容器类组件
default
菜单内容
适用的组件
- SelectMenuBody
- SelectMenuRow
- SelectMenuColumn
- SelectMenuSection
菜单项类
prepend
前置插槽default
主体内容插槽append
尾部插槽,向右对齐
适用的组件
- SelectMenuItem
- SelectMenuHeader
- SelectMenuSubHeader
SelectMenuDropdown 的插槽
trigger
打开菜单的触发对象default
菜单的主体内容
SelectMenuTrigger 的插槽
default
组件内置菜单触发按钮的显示文本,不设置则默认显示Open
文本append
触发按钮尾部的插槽,不设置则默认提供一个显示菜单打开状态的箭头图标