Tabs 标签页

在同一位置切换显示的几组内容。

转学第一天,我在天台遇见了那个抱着旧相机的少女。

<script setup lang="ts">
  import { Stack, Tabs, TabsContent, TabsList, TabsTrigger, Text } from '@hina-ui/vue'
</script>

<template>
  <Tabs default-value="intro" class="w-full max-w-md">
    <TabsList label="作品信息">
      <TabsTrigger value="intro">简介</TabsTrigger>
      <TabsTrigger value="volumes">卷册</TabsTrigger>
      <TabsTrigger value="staff">制作</TabsTrigger>
    </TabsList>
    <TabsContent value="intro">
      <Stack gap="xs" class="pt-4">
        <Text tone="muted" size="sm">转学第一天,我在天台遇见了那个抱着旧相机的少女。</Text>
      </Stack>
    </TabsContent>
    <TabsContent value="volumes">
      <Stack gap="xs" class="pt-4">
        <Text tone="muted" size="sm">全 7 卷,第 8 卷预定于今年冬季发行。</Text>
      </Stack>
    </TabsContent>
    <TabsContent value="staff">
      <Stack gap="xs" class="pt-4">
        <Text tone="muted" size="sm">作者 支倉凍砂,插画 文倉十。</Text>
      </Stack>
    </TabsContent>
  </Tabs>
</template>
vue

用法

import { Tabs, TabsList, TabsTrigger, TabsContent } from '@hina-ui/vue'
ts

组件由四部分构成:Tabs 持有当前选中项,TabsList 是页签所在的一行,TabsTrigger 是单个页签,TabsContent 是与之对应的内容。触发器与内容通过 value 一一对应。

正在读的 3 部作品。

<script setup lang="ts">
  import { Tabs, TabsContent, TabsList, TabsTrigger, Text } from '@hina-ui/vue'
</script>

<template>
  <Tabs default-value="reading" class="w-full max-w-md">
    <TabsList label="书架分类">
      <TabsTrigger value="reading">在读</TabsTrigger>
      <TabsTrigger value="planned">想读</TabsTrigger>
      <TabsTrigger value="finished">读过</TabsTrigger>
    </TabsList>
    <TabsContent value="reading">
      <Text tone="muted" size="sm" class="block pt-4">正在读的 3 部作品。</Text>
    </TabsContent>
    <TabsContent value="planned">
      <Text tone="muted" size="sm" class="block pt-4">收藏待读的 12 部作品。</Text>
    </TabsContent>
    <TabsContent value="finished">
      <Text tone="muted" size="sm" class="block pt-4">已经读完的 48 部作品。</Text>
    </TabsContent>
  </Tabs>
</template>
vue

页签用于在同一位置切换几组并列的内容,各组之间没有先后顺序。若内容需要同时可见,应改用分节的标题;若是一次操作的若干步骤,应使用 Stepper。

示例

形态

underline 为默认形态,选中项由一条圆头线标示,适合与正文同宽的内容分组;soft 的选中项是一块浮起的滑块,适合工具栏与紧凑的切换。

选中项由一条圆头线标示。

选中项由一块浮起的滑块标示。

<script setup lang="ts">
  import { Stack, Tabs, TabsContent, TabsList, TabsTrigger, Text } from '@hina-ui/vue'
</script>

<template>
  <Stack gap="lg" class="w-full max-w-md">
    <Tabs default-value="a" variant="underline">
      <TabsList label="下划线形态">
        <TabsTrigger value="a">underline</TabsTrigger>
        <TabsTrigger value="b">默认形态</TabsTrigger>
      </TabsList>
      <TabsContent value="a">
        <Text tone="muted" size="sm" class="block pt-3">选中项由一条圆头线标示。</Text>
      </TabsContent>
      <TabsContent value="b">
        <Text tone="muted" size="sm" class="block pt-3">适合与正文同宽的内容分组。</Text>
      </TabsContent>
    </Tabs>
    <Tabs default-value="a" variant="soft">
      <TabsList label="色块形态">
        <TabsTrigger value="a">soft</TabsTrigger>
        <TabsTrigger value="b">色块形态</TabsTrigger>
      </TabsList>
      <TabsContent value="a">
        <Text tone="muted" size="sm" class="block pt-3">选中项由一块浮起的滑块标示。</Text>
      </TabsContent>
      <TabsContent value="b">
        <Text tone="muted" size="sm" class="block pt-3">适合工具栏与紧凑的切换。</Text>
      </TabsContent>
    </Tabs>
  </Stack>
</template>
vue

标示选中项的那条线或滑块会随选中项平移与伸缩,不是瞬间跳转。

尺寸

size 改变的是这一行的疏密:sm 用于工具栏与密集界面,md 为默认,lg 用于页面顶部这类需要更多存在感的位置。

字号在三档中保持一致,页签属于界面 chrome,视觉分量由高度、内边距与选中标示给出。

sm

md

lg

<script setup lang="ts">
  import { Stack, Tabs, TabsContent, TabsList, TabsTrigger, Text } from '@hina-ui/vue'

  const sizes = ['sm', 'md', 'lg'] as const
</script>

<template>
  <Stack gap="lg" class="w-full max-w-md">
    <Stack v-for="size in sizes" :key="size" gap="xs">
      <Text tone="muted" size="sm">{{ size }}</Text>
      <Tabs default-value="a" :size="size">
        <TabsList :label="`${size} 档`">
          <TabsTrigger value="a">简介</TabsTrigger>
          <TabsTrigger value="b">卷册</TabsTrigger>
        </TabsList>
        <TabsContent value="a" />
        <TabsContent value="b" />
      </Tabs>
    </Stack>
  </Stack>
</template>
vue

纵向

将 orientation 设为 vertical,页签排成一列位于内容左侧,方向键随之改为上下切换。

用户名、邮箱与密码。

<script setup lang="ts">
  import { Tabs, TabsContent, TabsList, TabsTrigger, Text } from '@hina-ui/vue'
</script>

<template>
  <Tabs default-value="account" orientation="vertical" class="w-full max-w-md">
    <TabsList label="设置分组">
      <TabsTrigger value="account">账号</TabsTrigger>
      <TabsTrigger value="reading">阅读</TabsTrigger>
      <TabsTrigger value="notice">通知</TabsTrigger>
    </TabsList>
    <TabsContent value="account">
      <Text tone="muted" size="sm">用户名、邮箱与密码。</Text>
    </TabsContent>
    <TabsContent value="reading">
      <Text tone="muted" size="sm">字号、行距与翻页方向。</Text>
    </TabsContent>
    <TabsContent value="notice">
      <Text tone="muted" size="sm">更新提醒与站内消息。</Text>
    </TabsContent>
  </Tabs>
</template>
vue

页签过多时

页签超出容器宽度时,该行本身可以横向滚动,并且不显示滚动条:滚动位置由两端的边缘阴影提示,鼠标可直接在该行上滚动滚轮,键盘则通过方向键在页签之间循环。

科幻题材的作品列表。

<script setup lang="ts">
  import { Tabs, TabsContent, TabsList, TabsTrigger, Text } from '@hina-ui/vue'

  const genres = ['科幻', '悬疑', '日常', '校园', '治愈', '奇幻', '推理', '恋爱', '历史', '战记']
</script>

<template>
  <Tabs default-value="科幻" class="w-full max-w-sm">
    <TabsList label="题材">
      <TabsTrigger v-for="genre in genres" :key="genre" :value="genre">{{ genre }}</TabsTrigger>
    </TabsList>
    <TabsContent v-for="genre in genres" :key="genre" :value="genre">
      <Text tone="muted" size="sm" class="block pt-4">{{ genre }}题材的作品列表。</Text>
    </TabsContent>
  </Tabs>
</template>
vue

禁用

在 TabsTrigger 上设置 disabled,该页签不可选中,方向键也会跳过它。

所有人都能看到这份书单。

<script setup lang="ts">
  import { Tabs, TabsContent, TabsList, TabsTrigger, Text } from '@hina-ui/vue'
</script>

<template>
  <Tabs default-value="public" class="w-full max-w-md">
    <TabsList label="可见范围">
      <TabsTrigger value="public">公开</TabsTrigger>
      <TabsTrigger value="friends">仅关注者</TabsTrigger>
      <TabsTrigger value="private" disabled>私密(需要登录)</TabsTrigger>
    </TabsList>
    <TabsContent value="public">
      <Text tone="muted" size="sm" class="block pt-4">所有人都能看到这份书单。</Text>
    </TabsContent>
    <TabsContent value="friends">
      <Text tone="muted" size="sm" class="block pt-4">只有关注你的人能看到。</Text>
    </TabsContent>
    <TabsContent value="private">
      <Text tone="muted" size="sm" class="block pt-4">只有自己可见。</Text>
    </TabsContent>
  </Tabs>
</template>
vue

无障碍

  • 为 TabsList 提供 label,说明这一组页签切换的是什么。
  • 方向键在页签之间移动,Home 与 End 跳到首尾,选中项随焦点变化。
  • 内容区可聚焦,以便键盘用户从页签直接进入内容。

API

Tabs

属性
类型
默认值
说明
modelValue
string
—
当前选中项,支持 v-model
defaultValue
string
—
初始选中项
variant
'underline' | 'soft'
'underline'
形态
size
'sm' | 'md' | 'lg'
'md'
尺寸
orientation
'horizontal' | 'vertical'
'horizontal'
排列方向
class
string
—
追加至根元素的类名

TabsList

属性
类型
默认值
说明
label
string
—
这一组页签的名称
class
string
—
追加至该行的类名

TabsTrigger

属性
类型
默认值
说明
value
string
—
与内容对应的标识,必填
disabled
boolean
false
是否不可选中
class
string
—
追加至页签的类名

TabsContent

属性
类型
默认值
说明
value
string
—
与页签对应的标识,必填
class
string
—
追加至内容区的类名