Popover 气泡弹出框 - Vant 4
💬 Popover 气泡弹出框
🎯 介绍
Popover 组件是弹出式的气泡菜单,支持基于触发元素精准定位、浅色/深色主题、箭头指示等,让操作选项更直观、轻量。
📦 引入
通过以下方式来全局注册组件,更多注册方式请参考组件注册。
import { createApp } from'vue'; import { Popover } from'vant'; const app = createApp(); app.use(Popover);🎯 代码演示
🔧 基础用法
当 Popover 弹出时,会基于 reference 插槽的内容进行定位,就像一个智能的小助手,总是知道在哪里出现最合适 🎯
<van-popover
v-model:show="showPopover"
:actions="actions"
@select="onSelect"
placement="bottom-start"
>
<template #reference>
<van-button type="primary">浅色风格</van-button>
</template>
</van-popover>import { ref } from 'vue';
import { showToast } from 'vant';
export default {
setup() {
const showPopover = ref(false);
// 通过 actions 属性来定义菜单选项,每个选项都是一个小功能 ⚡
const actions = [
{ text: '选项一' },
{ text: '选项二' },
{ text: '选项三' },
];
const onSelect = (action) => showToast(action.text);
return {
actions,
onSelect,
showPopover,
};
},
};🌙 深色风格
Popover 支持浅色和深色两种风格,默认为浅色风格,将 theme 属性设置为 dark 可切换为深色风格,给用户带来不同的视觉体验 🌃
<van-popover
v-model:show="showPopover"
theme="dark"
:actions="actions"
placement="bottom-start"
>
<template #reference>
<van-button type="primary">深色风格</van-button>
</template>
</van-popover>import { ref } from 'vue';
export default {
setup() {
const showPopover = ref(false);
// 深色主题下的选项列表,营造神秘优雅氛围 🌙
const actions = [
{ text: '选项一' },
{ text: '选项二' },
{ text: '选项三' },
];
return {
actions,
showPopover,
};
},
};📐 水平排列
将 actions-direction 属性设置为 horizontal 后,菜单选项会变成水平排列,就像一排整齐的小士兵 🎖️
<van-popover
v-model:show="showPopover"
:actions="actions"
actions-direction="horizontal"
placement="bottom-start"
>
<template #reference>
<van-button type="primary">水平排列</van-button>
</template>
</van-popover>import { ref } from 'vue';
export default {
setup() {
const showPopover = ref(false);
// 水平排列的选项,适合简洁的操作场景 ➡️
const actions = [
{ text: '选项一' },
{ text: '选项二' },
{ text: '选项三' },
];
return {
actions,
showPopover,
};
},
};🧭 弹出位置
通过 placement 属性来控制气泡的弹出位置,就像指南针一样精准定位 🧭
<van-popover
v-model:show="showPopover"
:actions="actions"
placement="top"
>
<template #reference>
<van-button type="primary">顶部弹出</van-button>
</template>
</van-popover>placement 支持以下值,覆盖所有方向:
top # 顶部中间位置 ⬆️
top-start # 顶部左侧位置 ↖️
top-end # 顶部右侧位置 ↗️
left # 左侧中间位置 ⬅️
left-start # 左侧上方位置 ↖️
left-end # 左侧下方位置 ↙️
right # 右侧中间位置 ➡️
right-start # 右侧上方位置 ↗️
right-end # 右侧下方位置 ↘️
bottom # 底部中间位置 ⬇️
bottom-start # 底部左侧位置 ↙️
bottom-end # 底部右侧位置 ↘️🎨 展示图标
在 actions 数组中,可以通过 icon 字段来定义选项的图标,支持传入图标名称或图片链接,让选项更加生动直观 🎨
<van-popover
v-model:show="showPopover"
:actions="actions"
placement="bottom-start"
>
<template #reference>
<van-button type="primary">展示图标</van-button>
</template>
</van-popover>import { ref } from 'vue';
export default {
setup() {
const showPopover = ref(false);
// 带图标的选项列表,图标让功能一目了然 ✨
const actions = [
{ text: '选项一', icon: 'add-o' },
{ text: '选项二', icon: 'music-o' },
{ text: '选项三', icon: 'more-o' },
];
return {
actions,
showPopover,
};
},
};🚫 禁用选项
在 actions 数组中,可以通过 disabled 字段来禁用某个选项,灰色状态提示用户当前不可操作 🚫
<van-popover
v-model:show="showPopover"
:actions="actions"
placement="bottom-start"
>
<template #reference>
<van-button type="primary">禁用选项</van-button>
</template>
</van-popover>import { ref } from 'vue';
export default {
setup() {
const showPopover = ref(false);
// 部分选项被禁用,提供更好的用户体验 ⛔
const actions = [
{ text: '选项一', disabled: true },
{ text: '选项二', disabled: true },
{ text: '选项三' },
];
return {
actions,
showPopover,
};
},
};🎭 自定义内容
通过默认插槽,可以在 Popover 内部放置任意内容,发挥无限创意 🎭
<van-popover v-model:show="showPopover" placement="top">
<van-grid
square
clickable
:border="false"
column-num="3"
style="width: 240px;"
>
<van-grid-item
v-for="i in 6"
:key="i"
text="选项"
icon="photo-o"
/>
</van-grid>
<template #reference>
<van-button type="primary">自定义内容</van-button>
</template>
</van-popover>import { ref } from 'vue';
export default {
setup() {
const showPopover = ref(false);
return { showPopover };
},
};🎮 非受控模式
你可以把 Popover 当做受控组件或非受控组件使用,灵活适应不同的使用场景 🎮
- 当绑定
v-model:show时,Popover 为受控组件,此时组件的显示完全由v-model:show的值决定 🎛️ - 当未绑定
v-model:show时,Popover 为非受控组件,此时你可以通过show属性传入一个默认值,组件值的显示由组件自身控制 🤖
<van-popover
:actions="actions"
placement="bottom-start"
@select="onSelect"
>
<template #reference>
<van-button type="primary">非受控模式</van-button>
</template>
</van-popover>import { ref } from 'vue';
import { showToast } from 'vant';
export default {
setup() {
// 非受控模式下的选项配置 🎯
const actions = [
{ text: '选项一' },
{ text: '选项二' },
{ text: '选项三' },
];
const onSelect = (action) => showToast(action.text);
return {
actions,
onSelect,
};
},
};API
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| v-model:show | 是否展示气泡弹出层,控制显示隐藏状态 👁️ | boolean | false |
| actions | 选项列表,定义弹出菜单的所有操作项 📋 | PopoverAction[] | [] |
actions-direction v4.4.1 | 选项列表的排列方向,可选值为 horizontal,让布局更灵活 📐 | PopoverActionsDirection | vertical |
| placement | 弹出位置,精准控制气泡出现的方向 🧭 | PopoverPlacement | bottom |
| theme | 主题风格,可选值为 dark,打造不同视觉体验 🎨 | PopoverTheme | light |
| trigger | 触发方式,可选值为 manual,控制如何激活弹出层 🎯 | PopoverTrigger | click |
| duration | 动画时长,单位秒,设置为 0 可以禁用动画,让过渡更流畅 ⏱️ | *number | string* |
| offset | 出现位置的偏移量,微调弹出层的精确位置 📏 | [number, number] | [0, 8] |
| overlay | 是否显示遮罩层,提供更好的焦点管理 🎭 | boolean | false |
| overlay-class | 自定义遮罩层类名,个性化遮罩样式 🎨 | *string | Array |
| overlay-style | 自定义遮罩层样式,精细控制遮罩外观 ✨ | object | - |
| show-arrow | 是否展示小箭头,增强指向性提示 ➡️ | boolean | true |
| close-on-click-action | 是否在点击选项后关闭,优化交互体验 🔄 | boolean | true |
| close-on-click-outside | 是否在点击外部元素后关闭菜单,提供直观的关闭方式 👆 | boolean | true |
| close-on-click-overlay | 是否在点击遮罩层后关闭菜单,增加关闭途径 🎭 | boolean | true |
| teleport | 指定挂载的节点,等同于 Teleport 组件的 to 属性,控制渲染位置 🚀 | *string | Element* |
| icon-prefix | 图标类名前缀,等同于 Icon 组件的 class-prefix 属性,统一图标样式 🎨 | string | van-icon |
PopoverAction 数据结构
actions 属性是一个由对象构成的数组,数组中的每个对象配置一列,对象可以包含以下值:
| 键名 | 说明 | 类型 |
|---|---|---|
| text | 选项文字,显示给用户的操作名称 📝 | string |
| icon | 文字左侧的图标,支持传入图标名称或图片链接,等同于 Icon 组件的 name 属性,让选项更直观 🎨 | string |
| color | 选项文字颜色,自定义文字显示颜色 🌈 | string |
| disabled | 是否为禁用状态,控制选项是否可点击 🚫 | boolean |
| className | 为对应选项添加额外的类名,实现个性化样式 ✨ | *string |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| select | 点击选项时触发,处理用户的选择操作 🎯 | action: PopoverAction, index: number |
| open | 打开菜单时触发,弹出层显示时的回调 📂 | - |
| close | 关闭菜单时触发,弹出层隐藏时的回调 📁 | - |
| opened | 打开菜单且动画结束后触发,完全显示后的回调 ✨ | - |
| closed | 关闭菜单且动画结束后触发,完全隐藏后的回调 🎭 | - |
| click-overlay | 点击遮罩层时触发,提供额外的交互反馈 👆 | event: MouseEvent |
Slots
| 名称 | 说明 | 参数 |
|---|---|---|
| default | 自定义菜单内容,完全控制弹出层内容 🎨 | - |
| reference | 触发 Popover 显示的元素内容,定义触发区域 🎯 | - |
| action | 自定义选项内容,个性化每个操作项的显示 ✨ | { action: PopoverAction, index: number } |
类型定义
组件导出以下类型定义:
importtype { PopoverProps, PopoverTheme, PopoverAction, PopoverActionsDirection, PopoverTrigger, PopoverPlacement, } from'vant';主题定制
样式变量
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 ConfigProvider 组件。
| 名称 | 默认值 | 描述 |
|---|---|---|
| --van-popover-arrow-size | 6px | 箭头大小,控制指向箭头的尺寸 ➡️ |
| --van-popover-radius | var(--van-radius-lg) | 圆角大小,打造圆润的视觉效果 🔘 |
| --van-popover-action-width | 128px | 选项宽度,控制每个操作项的宽度 📏 |
| --van-popover-action-height | 44px | 选项高度,设置操作项的垂直空间 📐 |
| --van-popover-action-font-size | var(--van-font-size-md) | 选项字体大小,调整文字显示尺寸 🔤 |
| --van-popover-action-line-height | var(--van-line-height-md) | 选项行高,优化文字垂直对齐 📏 |
| --van-popover-action-icon-size | 20px | 选项图标大小,控制图标显示尺寸 🎨 |
| --van-popover-horizontal-action-height | 34px | 水平排列选项高度,适配横向布局 ↔️ |
| --van-popover-horizontal-action-icon-size | 16px | 水平排列图标大小,优化横向显示 🎯 |
| --van-popover-light-text-color | var(--van-text-color) | 浅色主题文字颜色,清晰易读 ☀️ |
| --van-popover-light-background | var(--van-background-2) | 浅色主题背景色,简洁明亮 🌞 |
| --van-popover-light-action-disabled-text-color | var(--van-text-color-3) | 浅色主题禁用文字颜色,提示不可用状态 🚫 |
| --van-popover-dark-text-color | var(--van-white) | 深色主题文字颜色,对比鲜明 🌙 |
| --van-popover-dark-background | #4a4a4a | 深色主题背景色,沉稳优雅 🌃 |
| --van-popover-dark-action-disabled-text-color | var(--van-text-color-2) | 深色主题禁用文字颜色,保持视觉层次 ⚫ |
常见问题
Popover 的点击事件无法正确触发?
这种情况通常是由于项目中引入了 fastclick 库导致的。建议移除 fastclick,或者配置 fastclick 的 ignore 规则。
相关文档
探索更多相关组件,打造完整的交互体验:
Popup 弹出层 - 通用弹出层容器,提供基础的弹出功能 📱
Dialog 弹出框 - 模态对话框,处理重要信息确认 💬
Overlay 遮罩层 - 页面遮罩组件,创建焦点效果 🎭
Toast 轻提示 - 轻量级消息提示,快速反馈用户操作 💭
Notify 消息通知 - 顶部消息通知,重要信息展示 📢
DropdownMenu 下拉菜单 - 下拉选择菜单,筛选和选择功能 🔽