5.4 KiB
5.4 KiB
title, description
| title | description |
|---|---|
| Tabs 标签页 | 在同一区域切换多个内容面板,首次激活才挂载、切换不销毁 |
Tabs 标签页
Tabs 在同一块区域里切换多个内容面板。它与 Segmented 的区别是:Tabs 负责「选择 + 内容区 + 懒渲染」,Segmented 只负责「选择」。
何时使用
- 同一对象的不同维度(基本信息 / 配置 / 权限)需要分区展示时;
- 面板内容较重(表格、图表、表单)时,Tabs 的懒渲染能避免一次性挂载所有面板;
- 纯视图模式切换、没有独立内容区时用 Segmented 更轻。
声明式写法
G3TabPane 只作声明,不渲染 DOM:tab-key 是唯一标识(不传按声明顺序取索引),label 是标签文字。
数据源写法
items 提供时优先于插槽;content 可以是字符串、VNode 或返回 VNode 的函数。标签动态来自接口时用这种写法。
位置
placement="left" | "right" 时标签栏纵向排列,指示条自动贴到对应边。
视觉风格
type="line" 是下划线指示条(默认),type="pill" 是胶囊式;centered 让标签栏居中。
只要标签栏
navOnly 时不渲染内容区,内容由外部(路由、分栏)控制;配合 #label、#leftExtra、#rightExtra 可以定制标签与两端内容。
键盘操作
标签栏是标准的 role="tablist":Tab 进入标签栏后,用左右键(top 位置)或上下键(left / right 位置)切换,Home / End 跳首尾;禁用的标签会被跳过。
面板生命周期
面板首次激活才挂载,之后切换只切换显隐(v-show),因此:
- 表单输入、滚动位置、图表实例在切换后不会丢;
- 未访问过的面板不会发请求(适合「概览 / 明细有重请求」的场景);
- 如果面板里有需要「每次进入都刷新」的数据,请在
change事件里自行处理。
API
Props(Tabs)
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue |
string | number |
— | 双向绑定的激活面板 key(内部按字符串比较,事件回传原始类型) |
placement |
'top' | 'left' | 'right' |
'top' |
标签栏位置 |
type |
'line' | 'pill' |
'line' |
视觉风格 |
navOnly |
boolean |
false |
只渲染标签栏,不渲染内容区 |
centered |
boolean |
false |
标签栏居中 |
disabled |
boolean |
false |
禁用整组 |
items |
TabItem[] |
— | 数据源;提供且非空时优先于 G3TabPane 插槽 |
Props(TabPane)
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
tabKey |
string | number |
声明顺序索引 | 唯一标识 |
label |
string |
— | 标签文本(有 #label 插槽时忽略) |
disabled |
boolean |
false |
禁用该标签 |
Events(Tabs)
| 名称 | 参数 | 说明 |
|---|---|---|
update:modelValue |
(key: string | number) |
激活项变化(回传原始类型的 key) |
change |
(key: string | number) |
仅在实际切换时触发(点当前标签不触发) |
tabClick |
(key: string | number, event: MouseEvent) |
点击即触发(含点当前标签);键盘切换不触发 |
Slots
| 名称 | 参数 | 说明 |
|---|---|---|
default |
— | G3TabPane 列表(items 模式下可省) |
label |
{ item, index } |
自定义标签渲染 |
leftExtra |
— | 标签栏左端内容 |
rightExtra |
— | 标签栏右端内容 |
类型定义
export type TabsPlacement = 'top' | 'left' | 'right'
export type TabsType = 'line' | 'pill'
export type TabKey = string | number
export interface TabItem {
key: TabKey
label?: string | VNode
disabled?: boolean
content?: VNode | (() => VNode)
}
export interface TabPaneProps {
tabKey?: TabKey
label?: string
disabled?: boolean
}
样式变量
| 变量 | 默认值 | 说明 |
|---|---|---|
--g3-tabs-tab-height |
38px |
标签项高度(故意高于控件档位,便于点击) |
--g3-color-primary |
#18181b |
激活项文字与指示条颜色 |
--g3-border-color |
#d9d9d9 |
标签栏底部分隔线 |
实现说明
- 受控/非受控:不传
modelValue时内部维护激活项。若受控值指向不存在或已禁用的面板,会回退显示第一个可用项,但不回写——这样受控语义保持干净(否则会在渲染期偷偷改你的状态); - **标签栏用原生 radio 语义吗?**不是:Tabs 用的是
role="tablist"+role="tab"+role="tabpanel"与 roving tabindex(只有激活项tabindex=0),键盘切换后主动focus()到目标标签,保证焦点可见; - 懒渲染缓存:
renderedKeys记录「访问过的 key」,模板用v-if控制挂载、v-show控制显隐,因此切换不会重建 DOM,也就不会丢内部状态; - 标签栏溢出时横向滚动(隐藏原生滚动条),标签不换行——避免出现两行标签把内容区挤下去;
- 指示条不使用 JS 测量:它就是每个标签自身的
border-bottom-color(left/right 位置对应border-right/left),因此字体缩放、文案长度变化都不会错位,也不需要ResizeObserver。