TinyRobot SuggestionPopover:智能建议弹出框组件
在 AI 驱动的对话界面中,用户真正需要的是一种更自然的交互引导方式。当 AI 助手准备提供一组可选建议时,一个恰到好处的弹出框既能承载足够的信息密度,又不会让操作变得繁琐。SuggestionPopover 正是为这种场景量身打造——点击触发器,浮层展开,建议列表清晰呈现,用户一眼即可锁定目标,一键完成选择。

该组件的核心价值体现在以下几个方面:
- 引导式交互:将建议项集中放置在弹出框中,界面整洁而不杂乱
- 上下文帮助:在对话流程的适当时机提供选项,不打断对话上下文
- 灵活的数据结构:既支持平铺列表,也支持分组列表,可根据需求自由选择
- 丰富的自定义能力:触发器、列表项、头部、内容区……所需插槽一应俱全
- 状态管理:内置 loading 和 empty 状态,无需额外处理
- 移动端适配:窗口宽度小于 768px 时自动切换为移动端样式,省心省力
基本用法:带数据的弹出框
通过 data 属性传入建议数据,再用 trigger 插槽自定义触发器。点击按钮,弹出列表,操作直观便捷。
触发方式:click 与 manual
SuggestionPopover 提供两种触发方式,通过 trigger 属性配置:
'click'(默认值):点击触发器时自动弹出或关闭,简单省心'manual':需要配合show属性(支持v-model)手动控制显示与隐藏,适合需要精确控场的场景
说到 manual 模式,它的应用场景其实很典型——比如当 AI 回复完成后,需要按照业务逻辑自动弹出建议,这时手动控制就派上用场了。
分组建议数据
如果建议项数量较多且类别分明,分组数据格式能大幅提升浏览效率。在 data 数组中传入 SuggestionGroup 对象,用 group 字段标识分组,items 字段包含该分组下的建议项。这样展示出来,用户一目了然。
注意:分组数据和普通数据不可混用——data 数组中的项要么全是 SuggestionItem,要么全是 SuggestionGroup,二选一。
selectedGroup 支持 v-model,可以设置默认选中的分组,也能在用户切换时获取当前分组。groupShowMoreTrigger 属性控制分组“显示更多”的触发方式,支持 'click' 和 'hover',按需选用即可。
自定义列表项渲染
通过 item 插槽,每个建议项的渲染形式完全由你掌控。插槽参数为 { item },你可以在 SuggestionItem 中添加任意自定义字段,然后按自己的风格展示。
{{ item.tag }}
{{ item.text }}
加载和空状态
SuggestionPopover 内置了 loading 和 empty 两种状态。通过 loading 属性显式开启加载状态;当 data 为空数组时,自动显示空状态。两个状态都提供了对应的插槽(loading 和 empty),你可以按需自定义展示效果。
正在获取建议...
暂无建议项
Header 和 Body 插槽
除了 item、loading、empty,SuggestionPopover 还提供了 header 和 body 插槽,用于完全接管弹出框的头部和内容区。下面是它的内部结构:
+---------------------------+
| SuggestionPopover |
| +---------------------+ |
| | header | |
| +---------------------+ |
| | | |
| | body | |
| | +-------------+ | |
| | | item[] | | |
| | +-------------+ | |
| | | |
| | loading / empty | |
| +---------------------+ |
+---------------------------+
- 使用
header插槽时,会替换默认的标题区域 - 使用
body插槽时,会替换整个列表区域(包括 item 列表、loading 和 empty 状态)
常见问题
-
{{ item.text }}
移动端适配
SuggestionPopover 自带移动端适配逻辑。当视窗宽度小于 768px 时,弹出框会自动切换为移动端友好的展示样式——触控区域更大,布局更适合小屏幕。你基本无需额外处理,只需确保页面配置了正确的 viewport:
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
API 参考
Props
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
data | SuggestionData | 是 | - | 建议数据 |
title | string | 否 | - | 弹出框标题 |
icon | VNode | Component | 否 | - | 标题图标 |
show | boolean | 否 | - | 控制弹出框显示/隐藏,仅在 trigger 为 'manual' 时有效 |
trigger | 'click' | 'manual' | 否 | 'click' | 触发方式:点击或手动控制 |
selectedGroup | string | 否 | - | 当前选中分组,支持 v-model |
groupShowMoreTrigger | 'click' | 'hover' | 否 | - | 分组"显示更多"的触发方式 |
loading | boolean | 否 | false | 是否显示加载状态 |
topOffset | number | 否 | - | 顶部偏移量 |
Slots
| 插槽名 | 类型 | 说明 |
|---|---|---|
trigger | () => VNode | VNode[] | 自定义触发器 |
item | ({ item }: { item: SuggestionItem }) => VNode | VNode[] | 自定义渲染列表项 |
loading | () => VNode | VNode[] | 自定义加载状态显示 |
empty | () => VNode | VNode[] | 自定义空状态显示 |
header | () => VNode | VNode[] | 自定义头部区域 |
body | () => VNode | VNode[] | 自定义列表区域 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
item-click | item: SuggestionItem | 点击建议项时触发 |
group-click | group: SuggestionGroup | 点击分组时触发 |
open | - | 弹窗打开时触发 |
close | - | 弹窗关闭时触发 |
click-outside | event: MouseEvent | 点击弹窗外部区域时触发 |
Types
interface SuggestionItem {
id: string
text: string
}interface SuggestionGroup {
group: string
label: string
icon?: VNode | Component
items: SuggestionItem[]
}type SuggestionData = (SuggestionItem | SuggestionGroup)[]
OpenTiny NEXT 是一套企业级智能前端开发解决方案,以生成式 UI 和 WebMCP 两大核心技术为基础,对现有的 TinyVue 组件库、TinyEngine 低代码引擎等产品进行智能化升级,构建出面向 Agent 应用的前端 NEXT-SDKs、AI Extension、TinyRobot 智能助手、GenUI 等新产品,加速企业应用的智能化改造,实现 AI 理解用户意图并自主完成任务。
