交互组件
📋 更新历史
| 日期 | 版本 | 更新内容 |
|---|---|---|
| 2025-11-06 | v1.1.0 | 新增 Tab 选项卡组件、图表切换交互功能 |
PSUIP 提供了丰富的交互组件,支持用户操作和动态内容切换,为 AI 生成的界面增添交互能力。
Tab 选项卡组件
Tab 选项卡组件用于在有限空间内组织和切换多个内容面板,提供清晰的信息架构和流畅的用户体验。
基本语法
<tab bindingData="变量名" defaultTabKey="默认选项卡">
<tabPanel tabKey="选项卡1" tabTitle="选项卡标题1">
选项卡1的内容
</tabPanel>
<tabPanel tabKey="选项卡2" tabTitle="选项卡标题2">
选项卡2的内容
</tabPanel>
<tabPanel tabKey="选项卡3" tabTitle="选项卡标题3">
选项卡3的内容
</tabPanel>
</tab>语法说明
| 属性 | 必需 | 说明 |
|---|---|---|
bindingData | 是 | 绑定的数据变量名,用于管理当前激活的选项卡状态 |
defaultTabKey | 是 | 默认激活的选项卡 key 值 |
tabKey | 是 | 选项卡的唯一标识,用于切换和状态管理 |
tabTitle | 是 | 选项卡显示的标题文本 |
基础示例
<tab bindingData="mainTabs" defaultTabKey="analysis">
<tabPanel tabKey="analysis" tabTitle="数据分析">
<card:elegantTable>
## 销售数据分析
### 季度报表
| 季度 | 销售额 | 增长率 |
|------|--------|--------|
| Q1 | 1200万 | 15% |
| Q2 | 1450万 | 20% |
| Q3 | 1680万 | 16% |
| Q4 | 1920万 | 14% |
</card:elegantTable>
</tabPanel>
<tabPanel tabKey="trends" tabTitle="趋势预测">
<card:elegantStandard>
## 未来趋势
### 预测模型
基于历史数据的分析,预计下一季度将保持稳定增长态势。
[查看详细报告](https://example.com/report)
</card:elegantStandard>
</tabPanel>
<tabPanel tabKey="settings" tabTitle="系统设置">
<card:elegantList>
## 配置选项
### 显示设置
- 数据刷新频率
- 图表样式偏好
- 通知提醒方式
### 权限管理
- 数据访问权限
- 报表导出权限
- 共享设置
</card:elegantList>
</tabPanel>
</tab>状态管理机制
Tab 组件通过八要素的状态系统实现选项卡切换,主要涉及以下机制:
1. 数据绑定
"data": {
"mainTabs": "analysis" // 当前激活的选项卡 key
}mainTabs是bindingData指定的变量名- 初始值为
defaultTabKey指定的值
2. 事件触发
每个选项卡标签包含点击事件:
"events": [{
"runtimeEventKey": "tab_changed",
"nativeEventKey": "click",
"parameters": {
"dataKey": "mainTabs",
"tabKey": "trends"
}
}]- 点击选项卡时触发
tab_changed事件 - 更新
dataKey指定的变量为当前tabKey
3. 条件渲染
选项卡面板通过条件判断显示:
"condition": "mainTabs=analysis"- 只有当
mainTabs等于对应的tabKey时才渲染该面板
4. 条件样式
选项卡标签通过条件样式高亮显示:
"conditionStyle": {
"condition": "mainTabs=analysis",
"className": "tab-item-active",
"classStyle": {
"background": "{color.onprimary.white100}",
"borderRadius": "{dimension.borderradius.large}"
}
}- 激活状态的选项卡应用特殊样式
样式定制
Tab 组件的样式通过 styleConfig 定义,包含以下部分:
整体容器样式(tabContainer)
{
padding: "{dimension.padding.superloose} {dimension.padding.extraloose}",
background: "{color.basic.brand.0}",
borderRadius: "{dimension.borderradius.xl}",
border: "{dimension.borderwidth.base} solid {color.basic.opacity.black.7}"
}标签容器样式(tabList)
{
display: 'flex',
flexDirection: 'row',
padding: "{dimension.padding.tight}",
gap: "{dimension.gap.base}",
borderRadius: "{dimension.borderradius.xxxxl}",
background: "{color.basic.brand.1}"
}标签项样式(tabListItem)
普通状态(normal):
{
flexGrow: "1",
padding: "{dimension.padding.tight}"
}激活状态(active):
{
flexGrow: "1",
padding: "{dimension.padding.tight}",
background: "{color.onprimary.white100}",
borderRadius: "{dimension.borderradius.large}"
}内容面板样式(tabPanel)
{
padding: "{dimension.padding.base} {dimension.padding.semiloose}",
borderRadius: "{dimension.borderradius.large}",
background: "{color.surfacecontainer.white100}"
}高级用法
嵌套复杂组件
Tab 可以包含任意 PSUIP 组件:
<tab bindingData="dashboardTabs" defaultTabKey="overview">
<tabPanel tabKey="overview" tabTitle="总览">
<layout:row>
<card:headerPrecentCard>
## 关键指标
### 销售额
#### 2500万
本月销售总额
### 用户数
#### 15000
活跃用户数量
</card:headerPrecentCard>
</layout:row>
</tabPanel>
<tabPanel tabKey="charts" tabTitle="图表">
<card:headerCard>
## 数据可视化
[chart:bar|月度对比]
| 月份 | 销售额 |
|------|--------|
| 1月 | 800 |
| 2月 | 950 |
| 3月 | 1100 |
</card:headerCard>
</tabPanel>
</tab>多个 Tab 组合
可以在同一页面使用多个独立的 Tab 组件:
## 仪表板
<tab bindingData="topTabs" defaultTabKey="summary">
<tabPanel tabKey="summary" tabTitle="摘要">
<!-- 顶层 Tab 内容 -->
<tab bindingData="subTabs" defaultTabKey="detail1">
<tabPanel tabKey="detail1" tabTitle="详情1">
<!-- 嵌套 Tab 内容 -->
</tabPanel>
<tabPanel tabKey="detail2" tabTitle="详情2">
<!-- 嵌套 Tab 内容 -->
</tabPanel>
</tab>
</tabPanel>
<tabPanel tabKey="analytics" tabTitle="分析">
<!-- 其他内容 -->
</tabPanel>
</tab>使用场景
- 数据报表:在多个视图间切换(表格/图表/趋势)
- 设置面板:组织不同类别的配置选项
- 内容分类:展示不同类型的信息内容
- 工作流程:引导用户完成多步骤操作
注意事项
- 变量命名:
bindingData的变量名应具有描述性,避免冲突 - 唯一标识:每个
tabKey必须在同一个 Tab 组件中唯一 - 内容组织:合理规划选项卡数量(建议 3-6 个)
- 默认选项:确保
defaultTabKey对应的tabPanel存在 - 嵌套层级:避免过深的 Tab 嵌套(建议不超过 2 层)
图表切换交互
PSUIP 支持通过用户交互动态切换图表类型,提供灵活的数据可视化体验。
基本语法
点击图表切换
[chart:图表类型][event:chart_changed(类型1,类型2,类型3)]
| 列标题 | 数据 |
|--------|------|
| 数据行 | 数值 |通过按钮切换
[chart:图表类型][event:chart_changed(类型1,类型2,类型3)|style:button]
| 列标题 | 数据 |
|--------|------|
| 数据行 | 数值 |语法说明
| 语法部分 | 说明 |
|---|---|
[chart:图表类型] | 初始显示的图表类型 |
[event:chart_changed(...)] | 声明图表切换事件,括号内为切换顺序 |
|style:button | 可选,使用按钮样式进行交互 |
(类型1,类型2,...) | 可切换的图表类型列表,按顺序循环切换 |
点击图表切换示例
用户点击图表本身进行类型切换:
[chart:barh|AI-PC 市场份额][event:chart_changed(barh,bar,pie)]
| 品牌 | 市场份额 |
|------|----------|
| 联想 | 35% |
| 苹果 | 28% |
| 荣耀 | 18% |
| 华为 | 12% |
| 其他 | 7% |交互效果:
- 初始显示水平柱状图(
barh) - 点击图表 → 切换到垂直柱状图(
bar) - 再次点击 → 切换到饼状图(
pie) - 再次点击 → 回到水平柱状图(
barh) - 循环切换
按钮控制切换示例
通过独立按钮控制图表切换:
[chart:barh|产品销售数据][event:chart_changed(barh,bar,pie,donut_chart)|style:button]
| 产品 | 销量 |
|------|------|
| 产品A | 1200 |
| 产品B | 980 |
| 产品C | 850 |
| 产品D | 720 |交互效果:
- 图表右上角显示切换按钮
- 按钮文字默认为”新样式”
- 点击按钮切换图表类型
- 按钮悬停时显示完整文字
切换类型选择
可以根据数据特点选择合适的切换类型组合:
对比类数据切换
[chart:bar][event:chart_changed(bar,barh,grouped_line)]
| 季度 | 销售额 | 利润 |
|------|--------|------|
| Q1 | 1200 | 180 |
| Q2 | 1450 | 220 |
| Q3 | 1680 | 250 |
| Q4 | 1920 | 290 |适合切换类型:
bar↔barh:柱状图方向切换grouped_line:趋势对比
占比类数据切换
[chart:pie][event:chart_changed(pie,donut_chart)|style:button]
| 类别 | 占比 |
|------|------|
| 类别A | 45 |
| 类别B | 30 |
| 类别C | 25 |适合切换类型:
pie↔donut_chart:饼图与环形图切换
趋势类数据切换
[chart:grouped_line][event:chart_changed(grouped_line,area_chart,bar)]
| 月份 | 指标1 | 指标2 |
|------|-------|-------|
| 1月 | 100 | 120 |
| 2月 | 150 | 180 |
| 3月 | 180 | 200 |适合切换类型:
grouped_line:折线图area_chart:面积图bar:柱状图
事件机制
点击图表切换的八要素事件
"events": [{
"runtimeEventKey": "chart_changed",
"nativeEventKey": "click",
"dataEventKey": [],
"parameters": {
"chartTypes": ["barh", "bar", "pie"]
},
"EventTargetId": "dd-chart-id"
}]- 点击图表触发
chart_changed事件 chartTypes定义切换顺序EventTargetId指向图表元素
按钮切换的八要素事件
{
"type": "button_normal",
"events": [{
"runtimeEventKey": "chart_changed",
"nativeEventKey": "click",
"parameters": {
"chartTypes": ["barh", "bar", "pie"]
},
"EventTargetId": "dd-chart-id"
}]
}- 独立的按钮元素
- 事件目标指向图表
按钮样式定制
当使用 style:button 时,按钮样式由 styleConfig 定义:
event: {
button: {
text: '新样式',
metaType: 'button',
variant: 'chartButton',
style: {
position: 'absolute',
right: "{dimension.padding.loose}",
top: "{dimension.padding.loose}",
// 悬停展开效果
transition: 'all 0.5s ease'
}
}
}按钮特性:
- 默认显示首字”新”
- 悬停时展开显示完整文字”新样式”
- 渐变背景色
- 定位在图表右上角
使用场景
- 数据探索:让用户以不同视角查看数据
- 对比分析:在多种图表类型间快速切换对比
- 个性化展示:允许用户选择偏好的可视化方式
- 教学演示:展示同一数据的不同表现形式
最佳实践
-
类型选择:
- 选择互补的图表类型
- 确保所有类型都适合当前数据结构
- 避免包含过多切换选项(建议 2-4 种)
-
交互方式:
- 简单场景使用点击图表
- 复杂场景或需要明确引导时使用按钮
- 考虑移动端触摸体验
-
数据准备:
- 确保数据格式适配所有图表类型
- 提供合适的数据标签
- 控制数据行数保证性能
-
用户引导:
- 必要时提供切换提示
- 保持切换逻辑的一致性
- 考虑添加图表标题说明
注意事项
- 兼容性:确保所选图表类型都支持当前数据结构
- 性能:切换会重新渲染图表,注意数据量控制
- 状态保持:切换后图表状态会重置
- 移动端:在小屏幕上优先使用按钮切换方式
错误处理
当图表类型不兼容时:
- 保持当前图表类型不变
- 在控制台输出警告信息
- 不影响用户继续操作
<!-- 错误示例:树状图不支持简单表格数据 -->
[chart:bar][event:chart_changed(bar,tree_mind)]
| 类别 | 数值 |
|------|------|
| A | 100 |
<!-- 正确示例:兼容的图表类型 -->
[chart:bar][event:chart_changed(bar,barh,pie)]
| 类别 | 数值 |
|------|------|
| A | 100 |交互组件组合使用
Tab 组件和图表交互可以组合使用,创建更丰富的交互体验:
<tab bindingData="dataView" defaultTabKey="overview">
<tabPanel tabKey="overview" tabTitle="总览">
<card:headerCard>
## 销售概况
[chart:bar|季度对比][event:chart_changed(bar,pie,grouped_line)|style:button]
| 季度 | 销售额 |
|------|--------|
| Q1 | 1200 |
| Q2 | 1450 |
| Q3 | 1680 |
| Q4 | 1920 |
</card:headerCard>
</tabPanel>
<tabPanel tabKey="detail" tabTitle="详细数据">
<card:elegantTable>
## 详细分析
### 月度数据
| 月份 | 销售额 | 利润 | 增长率 |
|------|--------|------|--------|
| 1月 | 380 | 45 | 12% |
| 2月 | 420 | 52 | 15% |
| 3月 | 400 | 48 | 10% |
</card:elegantTable>
</tabPanel>
</tab>这种组合提供了多层次的数据探索能力:
- Tab 用于组织不同维度的数据
- 图表切换用于同一维度的不同视角
- 创造流畅的数据分析体验
Last updated on