跳到主要内容

Tabs

  • 组件说明:Tabs 用于在同一区域内组织和切换不同内容面板。对外 API 采用声明式配置:简单场景下 children 作为触发器,面板内容通过 items 配置。
  • 尺寸基线:容器高度=40px,标签间距=24px(Default/Underline)或 16px(Chevron)。
  • 实现约定ui/tabs 只保留结构骨架,design 层统一接管视觉 token。variant 直接在 Tabs 上配置。
  • Figma 规范

基础用法

结果
Loading...
实时编辑器
<Tabs
  defaultValue="tab1"
  items={[
    {
      value: 'tab1',
      label: '账户',
      content: <p style={{ padding: '16px 0', color: '#333' }}>管理您的账户设置和偏好。</p>,
    },
    {
      value: 'tab2',
      label: '设置',
      content: <p style={{ padding: '16px 0', color: '#333' }}>自定义应用程序设置。</p>,
    },
    {
      value: 'tab3',
      label: '通知',
      content: <p style={{ padding: '16px 0', color: '#333' }}>配置通知偏好。</p>,
    },
  ]}
/>

变体

3 种视觉变体,适配不同使用场景。

Default

纯文字标签页,最简视觉样式。

结果
Loading...
实时编辑器
<Tabs
  defaultValue="tab1"
  variant="default"
  items={[
    { value: 'tab1', label: 'Tab 1', content: <p style={{ padding: '16px 0' }}>Content 1</p> },
    { value: 'tab2', label: 'Tab 2', content: <p style={{ padding: '16px 0' }}>Content 2</p> },
    { value: 'tab3', label: 'Tab 3', content: <p style={{ padding: '16px 0' }}>Content 3</p> },
  ]}
/>

Underline

选中标签带 2px 底部边框指示。

结果
Loading...
实时编辑器
<Tabs
  defaultValue="tab1"
  variant="underline"
  items={[
    { value: 'tab1', label: 'Tab 1', content: <p style={{ padding: '16px 0' }}>Content 1</p> },
    { value: 'tab2', label: 'Tab 2', content: <p style={{ padding: '16px 0' }}>Content 2</p> },
    { value: 'tab3', label: 'Tab 3', content: <p style={{ padding: '16px 0' }}>Content 3</p> },
  ]}
/>

Chevron

选中标签显示下拉箭头图标,暗示可展开内容。

结果
Loading...
实时编辑器
<Tabs
  defaultValue="tab1"
  variant="chevron"
  items={[
    { value: 'tab1', label: 'Tab 1', content: <p style={{ padding: '16px 0' }}>Content 1</p> },
    { value: 'tab2', label: 'Tab 2', content: <p style={{ padding: '16px 0' }}>Content 2</p> },
    { value: 'tab3', label: 'Tab 3', content: <p style={{ padding: '16px 0' }}>Content 3</p> },
  ]}
/>

变体对比

三种变体并排展示。

结果
Loading...
实时编辑器
<div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>
  <div>
    <p style={{ fontSize: 12, color: '#999', marginBottom: 8 }}>Default</p>
    <Tabs
      defaultValue="tab1"
      variant="default"
      items={[
        { value: 'tab1', label: 'Tab 1' },
        { value: 'tab2', label: 'Tab 2' },
      ]}
    />
  </div>
  <div>
    <p style={{ fontSize: 12, color: '#999', marginBottom: 8 }}>Underline</p>
    <Tabs
      defaultValue="tab1"
      variant="underline"
      items={[
        { value: 'tab1', label: 'Tab 1' },
        { value: 'tab2', label: 'Tab 2' },
      ]}
    />
  </div>
  <div>
    <p style={{ fontSize: 12, color: '#999', marginBottom: 8 }}>Chevron</p>
    <Tabs
      defaultValue="tab1"
      variant="chevron"
      items={[
        { value: 'tab1', label: 'Tab 1' },
        { value: 'tab2', label: 'Tab 2' },
      ]}
    />
  </div>
</div>

禁用状态

可以单独禁用某个标签页。

结果
Loading...
实时编辑器
<Tabs
  defaultValue="tab1"
  variant="underline"
  items={[
    { value: 'tab1', label: '激活', content: <p style={{ padding: '16px 0' }}>激活内容</p> },
    {
      value: 'tab2',
      label: '禁用',
      disabled: true,
      content: <p style={{ padding: '16px 0' }}>禁用内容</p>,
    },
    { value: 'tab3', label: '正常', content: <p style={{ padding: '16px 0' }}>正常内容</p> },
  ]}
/>

滚动溢出

标签过多时,列表自动支持水平滚动,并显示左右导航箭头。

结果
Loading...
实时编辑器
<Tabs
  defaultValue="t1"
  variant="underline"
  items={[
    { value: 't1', label: '仪表盘', content: <p style={{ padding: '16px 0' }}>仪表盘内容</p> },
    { value: 't2', label: '分析' },
    { value: 't3', label: '报告' },
    { value: 't4', label: '通知' },
    { value: 't5', label: '设置' },
    { value: 't6', label: '集成' },
    { value: 't7', label: '账单' },
    { value: 't8', label: '安全' },
    { value: 't9', label: '团队' },
    { value: 't10', label: 'API 密钥' },
  ]}
/>

保留状态(destroyOnHidden)

默认情况下,非激活面板会从 DOM 卸载。设置 destroyOnHidden={false} 可保留面板在 DOM 中,保持内部状态(如滚动位置、表单输入)。

结果
Loading...
实时编辑器
const PreserveStateExample = () => {
  const [count, setCount] = useState(0)
  return (
    <Tabs
      defaultValue="tab1"
      items={[
        {
          value: 'tab1',
          label: '计数器',
          destroyOnHidden: false,
          content: (
            <div style={{ padding: '16px 0' }}>
              <p>计数: {count}</p>
              <button
                onClick={() => setCount((current) => current + 1)}
                style={{
                  marginTop: 8,
                  padding: '4px 12px',
                  border: '1px solid #ccc',
                  borderRadius: 4,
                }}
              >
                增加
              </button>
              <p style={{ fontSize: 12, color: '#999', marginTop: 8 }}>切换标签后计数不会丢失。</p>
            </div>
          ),
        },
        {
          value: 'tab2',
          label: '其他',
          destroyOnHidden: false,
          content: <p style={{ padding: '16px 0' }}>其他内容。返回查看计数仍在。</p>,
        },
      ]}
    />
  )
}

render(<PreserveStateExample />)

尺寸规范

维度
容器高度40px
标签间距(Default)24px
标签间距(Underline)24px
标签间距(Chevron)16px
字号14px
行高22px
选中字重500(medium)
未选中字重400(normal)
Underline 线条厚度2px
Chevron 图标尺寸20×20px

Props

Tabs

属性类型默认值说明
itemsTabsItem[]-声明式标签配置
variant'default' | 'underline' | 'chevron''default'视觉变体
defaultValuestring-默认激活标签(非受控)
valuestring-激活标签(受控)
onValueChange(value: string) => void-激活标签变化回调
classNamestring-外层容器类名
listClassNamestring-标签列表容器类名

TabsItem

字段类型默认值说明
valuestring-标签唯一标识值
labelReactNode-Trigger 展示内容
contentReactNode-面板内容
disabledbooleanfalse是否禁用该标签
triggerClassNamestring-Trigger 自定义类名
contentClassNamestring-面板自定义类名
destroyOnHiddenbooleantruefalse 时保留非激活面板 DOM