u
This commit is contained in:
1 parent
e99a9fb274
commit
0be0b0767a
788 files changed
+112023
-14941
No files matched your search
@@ -0,0 +1,132 @@
|
||||
---
|
||||
title: Tabs 标签页
|
||||
description: 在同一区域切换多个内容面板,首次激活才挂载、切换不销毁
|
||||
---
|
||||
|
||||
# Tabs 标签页
|
||||
|
||||
`Tabs` 在同一块区域里切换多个内容面板。它与 [Segmented](/ui/general/segmented) 的区别是:Tabs 负责「选择 + 内容区 + 懒渲染」,Segmented 只负责「选择」。
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 同一对象的不同维度(基本信息 / 配置 / 权限)需要分区展示时;
|
||||
- 面板内容较重(表格、图表、表单)时,Tabs 的懒渲染能避免一次性挂载所有面板;
|
||||
- 纯视图模式切换、没有独立内容区时用 Segmented 更轻。
|
||||
|
||||
## 声明式写法
|
||||
|
||||
`G3TabPane` 只作声明,不渲染 DOM:`tab-key` 是唯一标识(不传按声明顺序取索引),`label` 是标签文字。
|
||||
|
||||
<demo vue="tabs/basic.vue" />
|
||||
|
||||
## 数据源写法
|
||||
|
||||
`items` 提供时优先于插槽;`content` 可以是字符串、VNode 或返回 VNode 的函数。标签动态来自接口时用这种写法。
|
||||
|
||||
<demo vue="tabs/items.vue" />
|
||||
|
||||
## 位置
|
||||
|
||||
`placement="left" | "right"` 时标签栏纵向排列,指示条自动贴到对应边。
|
||||
|
||||
<demo vue="tabs/placement.vue" />
|
||||
|
||||
## 视觉风格
|
||||
|
||||
`type="line"` 是下划线指示条(默认),`type="pill"` 是胶囊式;`centered` 让标签栏居中。
|
||||
|
||||
<demo vue="tabs/type.vue" />
|
||||
|
||||
## 只要标签栏
|
||||
|
||||
`navOnly` 时不渲染内容区,内容由外部(路由、分栏)控制;配合 `#label`、`#leftExtra`、`#rightExtra` 可以定制标签与两端内容。
|
||||
|
||||
<demo vue="tabs/nav-only.vue" />
|
||||
|
||||
## 键盘操作
|
||||
|
||||
标签栏是标准的 `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` | — | 标签栏右端内容 |
|
||||
|
||||
### 类型定义
|
||||
|
||||
```ts
|
||||
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`。
|
||||
Reference in new issue
Block a user