DropdownMenu 下拉菜单 - Vant 4
📋 DropdownMenu 下拉菜单
🎯 介绍
想象一下,你正在浏览一个购物网站,面对琳琅满目的商品,是不是希望有个贴心的小助手帮你快速筛选?DropdownMenu 下拉菜单组件就是这样一个神奇的存在!✨
它就像一个智能的魔法盒子,轻轻一点就能展开各种选项,让用户在众多选择中轻松找到心仪的内容。无论是商品分类、排序方式,还是其他筛选条件,DropdownMenu 都能优雅地为你呈现,让复杂的选择变得简单有趣!🎪
📦 引入
通过以下方式来全局注册组件,更多注册方式请参考组件注册。
import { createApp } from'vue'; import { DropdownMenu, DropdownItem } from'vant'; const app = createApp(); app.use(DropdownMenu); app.use(DropdownItem);🎯 代码演示
🔧 基础用法
最简单的下拉菜单就像搭积木一样简单!只需要准备好选项数据,DropdownMenu 就能为你呈现一个美观实用的下拉选择器。看看下面这个例子,是不是很容易上手?🎮
import { ref } from'vue'; exportdefault { setup() { const value1 = ref(0); const value2 = ref('a'); const option1 = [ { text: '全部商品', value: 0 }, { text: '新款商品', value: 1 }, { text: '活动商品', value: 2 }, ]; const option2 = [ { text: '默认排序', value: 'a' }, { text: '好评排序', value: 'b' }, { text: '销量排序', value: 'c' }, ]; return { value1, value2, option1, option2, }; }, };🎨 自定义菜单内容
有时候标准的选项列表可能无法满足你的创意需求,别担心!DropdownMenu 就像一个百变魔术师,通过插槽功能,你可以在下拉菜单中放入任何你想要的内容 —— 开关按钮、滑块、甚至是一个小游戏!🎭
当你使用自定义内容时,记得要手动控制菜单的开关哦,就像遥控器控制电视一样简单!
import { ref } from'vue'; exportdefault { setup() { const menuRef = ref(null); const itemRef = ref(null); const value = ref(0); const switch1 = ref(false); const switch2 = ref(false); const options = [ { text: '全部商品', value: 0 }, { text: '新款商品', value: 1 }, { text: '活动商品', value: 2 }, ]; constonConfirm = () => { itemRef.value.toggle(); // 或者// menuRef.value.close(); }; return { menuRef, itemRef, value, switch1, switch2, options, onConfirm, }; }, };🌈 自定义选中态颜色
想让你的下拉菜单更有个性?就像给它换上不同颜色的新衣服一样!通过 active-color 属性,你可以让选中的选项穿上你喜欢的颜色外套,让整个界面更符合你的品牌调性。🎨
🏃♂️ 横向滚动
当选项太多,菜单栏装不下时怎么办?别慌!DropdownMenu 贴心地支持横向滚动功能,就像翻阅一本厚厚的相册一样,左右滑动就能看到更多选项。通过 swipe-threshold 属性,你还能自定义什么时候开启这个滚动魔法!📱
⬆️ 向上展开
有时候菜单需要"反其道而行之",向上展开!比如当按钮位于屏幕底部时,向上展开就能避免菜单被遮挡。只需要把 direction 设置为 up,菜单就会像气球一样向上飘起!🎈
🚫 禁用菜单
有些时候,某些菜单项可能暂时不可用,就像商店里的"暂时缺货"标签一样。通过禁用功能,你可以让用户知道这个选项目前不可选择,避免产生困惑。
API
DropdownMenu Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| active-color | 菜单标题和选项的选中态颜色 | string | #1989fa |
| direction | 菜单展开方向,可选值为up | string | down | | z-index | 菜单栏 z-index 层级 | number | string | 10 | | duration | 动画时长,单位秒,设置为 0 可以禁用动画 | number | string | 0.2 | | overlay | 是否显示遮罩层 | boolean | true | | close-on-click-overlay | 是否在点击遮罩层后关闭菜单 | boolean | true | | close-on-click-outside | 是否在点击外部元素后关闭菜单 | boolean | true | | swipe-threshold | 滚动阈值,选项数量超过阈值且总宽度超过菜单栏宽度时,可以横向滚动 | number | string | - | | auto-locate | 当祖先元素设置了 transform 时,自动调整下拉菜单的位置 | boolean | false |
DropdownItem Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| v-model | 当前选中项对应的 value | *number | string* |
| title | 菜单项标题 | string | 当前选中项文字 |
| options | 选项数组 | Option[] | [] |
| disabled | 是否禁用菜单 | boolean | false |
| lazy-render | 是否在首次展开时才渲染菜单内容 | boolean | true |
| title-class | 标题额外类名 | *string | Array |
| teleport | 指定挂载的节点,等同于 Teleport 组件的 to 属性 | *string | Element* |
DropdownItem Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| change | 点击选项导致 value 变化时触发 | value |
| open | 打开菜单栏时触发 | - |
| close | 关闭菜单栏时触发 | - |
| opened | 打开菜单栏且动画结束后触发 | - |
| closed | 关闭菜单栏且动画结束后触发 | - |
DropdownItem Slots
| 名称 | 说明 |
|---|---|
| default | 菜单内容 |
| title | 自定义菜单项标题 |
DropdownMenu 方法
通过 ref 可以获取到 DropdownMenu 实例并调用实例方法,详见组件实例方法。
| 方法名 | 说明 | 参数 | 返回值 |
|---|---|---|---|
| close | 关闭所有菜单的展示状态 | - | - |
DropdownItem 方法
通过 ref 可以获取到 DropdownItem 实例并调用实例方法,详见组件实例方法。
| 方法名 | 说明 | 参数 | 返回值 |
|---|---|---|---|
| toggle | 切换菜单展示状态,传 true 为显示,false 为隐藏,不传参为取反 | show?: boolean | - |
类型定义
组件导出以下类型定义:
importtype { DropdownMenuProps, DropdownItemProps, DropdownItemOption, DropdownItemInstance, DropdownMenuInstance, DropdownMenuDirection, } from'vant';DropdownMenuInstance 和 DropdownItemInstance 是组件实例的类型,用法如下:
import { ref } from'vue'; importtype { DropdownMenuInstance, DropdownItemInstance } from'vant'; const dropdownMenuRef = ref<DropdownMenuInstance>(); const dropdownItemRef = ref<DropdownItemInstance>(); dropdownMenuRef.value?.close(); dropdownItemRef.value?.toggle();Option 数据结构
| 键名 | 说明 | 类型 |
|---|---|---|
| text | 文字 | string |
| value | 标识符 | *number |
| disabled | 是否禁用选项 | boolean |
| icon | 左侧图标名称或图片链接,等同于 Icon 组件的 name 属性 | string |
主题定制
样式变量
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 ConfigProvider 组件。
| 名称 | 默认值 | 描述 |
|---|---|---|
| --van-dropdown-menu-height | 48px | - |
| --van-dropdown-menu-background | var(--van-background-2) | - |
| --van-dropdown-menu-shadow | 0 2px 12px fade(var(--van-gray-7), 12) | - |
| --van-dropdown-menu-title-font-size | 15px | - |
| --van-dropdown-menu-title-text-color | var(--van-text-color) | - |
| --van-dropdown-menu-title-active-text-color | var(--van-primary-color) | - |
| --van-dropdown-menu-title-disabled-text-color | var(--van-text-color-2) | - |
| --van-dropdown-menu-title-padding | 0 var(--van-padding-xs) | - |
| --van-dropdown-menu-title-line-height | var(--van-line-height-lg) | - |
| --van-dropdown-menu-option-active-color | var(--van-primary-color) | - |
| --van-dropdown-menu-option-disabled-color | var(--van-text-color-3) | - |
| --van-dropdown-menu-content-max-height | 80% | - |
| --van-dropdown-item-z-index | 10 | - |
🤔 常见问题
父元素设置 transform 后,下拉菜单的位置错误?
有时候你可能会发现下拉菜单像个迷路的小朋友,出现在了奇怪的位置。这通常发生在把 DropdownMenu 放在 Tabs 等设置了 transform 的组件内部时。
这就像在一个移动的火车车厢里放东西,坐标系统发生了变化!CSS 的 fixed 定位会相对于设置了 transform 的父元素计算位置,而不是相对于整个页面。
别担心,解决方法很简单!就像给迷路的小朋友指明回家的路一样,将 DropdownItem 的 teleport 属性设置为 body,让菜单直接"传送"到页面根部:
也可以将 DropdownMenu 的 auto-locate 属性设置为 true,让组件自动帮你找到正确的位置:
🔗 相关文档
在使用 DropdownMenu 的过程中,你可能还会用到这些相关组件,它们就像好朋友一样,经常一起出现在项目中:
- Popup 弹出层 - 下拉菜单的底层实现基础,了解它能帮你更好地理解菜单的工作原理
- ActionSheet 动作面板 - 另一种选择方式,特别适合移动端的底部弹出选择
- Picker 选择器 - 当选项较多且有层级关系时,Picker 是个不错的选择
- Tab 标签页 - 经常与 DropdownMenu 搭配使用,实现页面的分类和筛选功能
- NavBar 导航栏 - 下拉菜单常常放置在导航栏中,提供快速筛选功能
- Search 搜索 - 与下拉菜单配合,提供更强大的内容筛选能力
- Button 按钮 - 触发下拉菜单的常用组件
- Icon 图标 - 为菜单选项添加图标,让界面更加直观美观