Tabs
在同层内容视图间切换。中文惯用名:标签页。
稳定本期新增已接入
元信息
| 字段 | 值 |
|---|---|
| 规范 ID | component.tabs |
| 名称 | Tabs |
| 二级分类 | 导航(navigation) |
| 用途 | 在同层内容视图间切换 |
| 描述 | 中文惯用名:标签页。 |
预览
静态结构:Tabs 渲染为 data-slot="tabs"(flex flex-col gap-2)→ 页签栏 TabsList(data-slot="tabs-list" data-variant,default 为 bg-muted 胶囊容器 / line 为通栏下划线轨道)+ 触发器 TabsTrigger(data-slot="tabs-trigger",激活态由 data-active 驱动:default 变体为卡片底 + 边框 + 阴影,line 变体为底部 2px 主色线)+ 内容面板 TabsContent(data-slot="tabs-content",flex-1);每个页签内容经 renderChildren 渲染 DSL 子树,内容区 class / 样式由 contentClassName / contentStyle 与 item.className / item.style 合并(item 在后);未传 activeKey 时缺省激活第一个页签。本条 dsl 复用预览 TABS_NODE(概览 / 明细 / 设置三页签,明细页内放 Alert)。
DSL 结构
{
"type": "Tabs",
"props": {
"items": [
{
"key": "overview",
"label": "概览",
"children": [
{
"type": "Text",
"props": {
"text": "概览页签内容区。",
"style": {
"display": "block",
"padding": 8
}
}
}
]
},
{
"key": "detail",
"label": "明细",
"children": [
{
"type": "Alert",
"props": {
"variant": "info",
"showIcon": true,
"message": "页签内容可放任意 DSL 子树。"
}
}
]
},
{
"key": "setting",
"label": "设置",
"children": [
{
"type": "Text",
"props": {
"text": "设置页签内容区。",
"style": {
"display": "block",
"padding": 8
}
}
}
]
}
]
}
}何时用
何时使用
- 同层内容视图切换:详情页的「概览 / 明细 / 设置」,切换不离开当前页面与上下文。
- 内容量大但并列关系明确:把长页面切成若干等权页签,降低单屏密度。
- 需要页签栏形态区分主次:default 胶囊(区块内切换)/ line 下划线(页面级导航感)。
何时不用
- 导航到其他页面或模块:使用 Menu、NavigationMenu,页签不换路由(换路由应改选导航组件)。
- 有先后顺序的流程步骤:使用 Steps(Tabs 各页签等权、无进度语义)。
- 页签数量过多(超过 6~7 个):改用 Select / Segmented 或拆分页面。
变体
| 变体 | 视觉形态 | 适用场景 |
|---|---|---|
| default 胶囊 | 灰底容器 + 激活项卡片底阴影 | 区块内视图切换(卡片、面板里) |
| line 下划线 | 通栏下划线轨道 + 激活项主色线 | 页面级主视图切换 |
| 受控切换 | activeKey 绑 state,onChange 回写 | 需要与路由 / 外部状态联动的页签 |
| 异质内容 | 页签内容放任意 DSL 子树(表格 / 表单 / 图表) | 详情页不同视角的内容组织 |
API 属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
items | TabItem[] | [] | 页签定义:{ key, label, children?(DSL 子树), className?, style? } |
activeKey | string | — | 当前激活页签 key(可绑表达式);缺省激活第一个页签 |
variant | `'default' | 'line'` | 'default' |
onChange | (key: string) => void | — | 页签切换事件,传出新激活 key(Renderer 绑定 events.onChange) |
contentClassName | string | — | 页签内容区 class(TabsContent 根节点,与内置样式合并) |
contentStyle | CSSProperties | — | 页签内容区内联样式(同 contentClassName 挂载规则) |
className / style | string / CSSProperties | — | 通用:根节点 class 合并 / 内联样式 |
使用规范
- 页签数量 2 ~ 6 个,标签用 2 ~ 4 字名词短语(「概览」「明细」),等长等权排列。
- 页签切换不改变页面 URL 与面包屑;需要路由变化时改用导航组件。
- 各页签内容首屏高度接近,避免切换时页面高度剧烈跳动。
- 页签内容惰性 / 性能敏感时按需在内容区放 Skeleton,避免一次渲染全部面板。
- 与外部状态联动时用 activeKey + onChange 受控(如与 URL query 同步)。
正例
- ✓ 资源详情页:概览 / 明细 / 设置三页签,各自承载不同视图。
- ✓ 配置面板:activeKey 绑 state,切换页签时按需加载该面板数据。
反例
- ✕ 用 Tabs 承载「基础信息 / 安全设置」这类会切换路由的页面(应使用 Menu)。
- ✕ 把线性流程(提交 → 审核 → 完成)做成 Tabs(应使用 Steps)。
Design Token 映射
不适用:组件 tokenRefs 为空:样式 Token 数据尚未接入,三层映射(Primitive → Semantic → Component)待样式 Token 接入后回填。