Files
workspace/code/g3soft-libs/docs/content/ui/data/tabs.md
T
2026-10-09 17:32:14 +08:00

5.4 KiB
Raw Blame History

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。