选项卡

轻松创建可访问、完全可定制的选项卡界面,具有强大的焦点管理和键盘导航支持。

要开始,请通过 npm 安装无状态 UI

npm install @headlessui/vue

选项卡是使用 TabGroupTabListTabTabPanelsTabPanel 组件构建的。默认情况下,第一个选项卡处于选中状态,单击任何选项卡或使用键盘选择它将激活相应的面板。

<template> <TabGroup> <TabList> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </TabList> <TabPanels> <TabPanel>Content 1</TabPanel> <TabPanel>Content 2</TabPanel> <TabPanel>Content 3</TabPanel> </TabPanels> </TabGroup> </template> <script setup> import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue' </script>

无状态 UI 会跟踪每个组件的许多状态,例如当前选中的选项卡选项,弹出窗口是打开还是关闭,或菜单中哪个项目当前通过键盘处于活动状态。

但由于这些组件是无状态的,并且在开箱即用时完全没有样式,因此您无法在 UI 中看到此信息,直到您自己为每个状态提供所需的样式。

每个组件都通过 插槽属性 公开有关其当前状态的信息,您可以使用这些属性有条件地应用不同的样式或呈现不同的内容。

例如,Tab 组件公开了一个 selected 状态,它告诉您选项卡当前是否处于选中状态。

<template> <TabGroup> <TabList> <!-- Use the `selected` state to conditionally style the selected tab. -->
<Tab as="template" v-slot="{ selected }">
<button
:class="{ 'bg-blue-500 text-white': selected, 'bg-white text-black': !selected }"
>
Tab 1 </button> </Tab> <!-- ... --> </TabList> <TabPanels> <TabPanel>Content 1</TabPanel> <!-- ... --> </TabPanels> </TabGroup> </template> <script setup> import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue' </script>

有关每个组件的完整插槽属性 API,请参阅 组件 API 文档

每个组件还通过一个 data-headlessui-state 属性公开有关其当前状态的信息,您可以使用它有条件地应用不同的样式。

插槽属性 API 中的任何状态为 true 时,它们将作为以空格分隔的字符串列在此属性中,以便您可以使用 CSS 属性选择器[attr~=value] 形式进行定位。

例如,以下是如何在第二个选项卡处于 selected 状态时渲染 TabGroup 组件和一些子 Tab 组件

<!-- Rendered `TabGroup` --> <div> <button data-headlessui-state="">Tab 1</button> <button data-headlessui-state="selected">Tab 2</button> <button data-headlessui-state="">Tab 3</button> </div> <div> <div data-headlessui-state="">Content 1</div> <div data-headlessui-state="selected">Content 2</div> <div data-headlessui-state="">Content 3</div> </div>

如果您使用的是 Tailwind CSS,则可以使用 @headlessui/tailwindcss 插件来使用像 ui-open:* 这样的修饰符定位此属性

<template> <TabGroup> <TabList> <Tab
class="ui-selected:bg-blue-500 ui-selected:text-white ui-not-selected:bg-white ui-not-selected:text-black"
>
Tab 1 </Tab> <!-- ... --> </TabList> <TabPanels> <TabPanel>Content 1</TabPanel> <!-- ... --> </TabPanels> </TabGroup> </template> <script setup> import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue' </script>

要禁用选项卡,请在 Tab 组件上使用 disabled 属性。禁用的选项卡不能用鼠标选择,并且在使用键盘浏览选项卡列表时也会跳过。

<template> <TabGroup> <TabList> <Tab>Tab 1</Tab>
<Tab disabled>Tab 2</Tab>
<Tab>Tab 3</Tab> </TabList> <TabPanels> <TabPanel>Content 1</TabPanel> <TabPanel>Content 2</TabPanel> <TabPanel>Content 3</TabPanel> </TabPanels> </TabGroup> </template> <script setup> import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue' </script>

默认情况下,当用户使用箭头键浏览它们时,选项卡会自动选中。

如果您不想在用户按下 EnterSpace 之前更改当前选项卡,请在 TabGroup 组件上使用 manual 属性。如果选择选项卡会执行昂贵的操作,并且您不想不必要地运行它,这可能会有所帮助。

<template>
<TabGroup manual>
<TabList> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </TabList> <TabPanels> <TabPanel>Content 1</TabPanel> <TabPanel>Content 2</TabPanel> <TabPanel>Content 3</TabPanel> </TabPanels> </TabGroup> </template> <script setup> import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue' </script>

manual 属性不会影响鼠标交互——选项卡在被点击后仍然会立即被选中。

如果您已将 TabList 的样式设置为垂直显示,请使用 vertical 属性来启用使用向上和向下箭头键而不是向左和向右键进行导航,以及更新辅助技术的 aria-orientation 属性。

<template>
<TabGroup vertical>
<TabList> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </TabList> <TabPanels> <TabPanel>Content 1</TabPanel> <TabPanel>Content 2</TabPanel> <TabPanel>Content 3</TabPanel> </TabPanels> </TabGroup> </template> <script setup> import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue' </script>

要更改默认情况下选中的选项卡,请在 TabGroup 组件上使用 :defaultIndex="number" 属性。

<template>
<TabGroup :defaultIndex="1">
<TabList> <Tab>Tab 1</Tab>
<!-- Selects this tab by default -->
<Tab>Tab 2</Tab>
<Tab>Tab 3</Tab> </TabList> <TabPanels> <TabPanel>Content 1</TabPanel>
<!-- Displays this tab by default -->
<TabPanel>Content 2</TabPanel>
<TabPanel>Content 3</TabPanel> </TabPanels> </TabGroup> </template> <script setup> import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue' </script>

如果您恰好提供了超出范围的索引,那么在初始渲染时将选择最后一个未禁用的选项卡。(例如,在上面的示例中,<TabGroup :defaultIndex="5" 将渲染第三个面板作为选中状态。)

要每当选中的选项卡发生更改时运行一个函数,请在 TabGroup 组件上使用 @change 事件。

<template>
<TabGroup @change="changeTab">
<TabList> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </TabList> <TabPanels> <TabPanel>Content 1</TabPanel> <TabPanel>Content 2</TabPanel> <TabPanel>Content 3</TabPanel> </TabPanels> </TabGroup> </template> <script setup> import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue'
function changeTab(index) {
console.log('Changed active tab to:', index)
}
</script>

选项卡组件也可以用作受控组件。为此,请提供 selectedIndex 并自己管理状态。

<template>
<TabGroup :selectedIndex="selectedTab" @change="changeTab">
<TabList> <Tab>Tab 1</Tab> <Tab>Tab 2</Tab> <Tab>Tab 3</Tab> </TabList> <TabPanels> <TabPanel>Content 1</TabPanel> <TabPanel>Content 2</TabPanel> <TabPanel>Content 3</TabPanel> </TabPanels> </TabGroup> </template> <script setup> import { ref } from 'vue' import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@headlessui/vue'
const selectedTab = ref(0)
function changeTab(index) {
selectedTab.value = index
}
</script>

单击 Tab 将选中该选项卡并显示相应的 TabPanel

Tab 组件获得焦点时,所有交互都适用。

命令描述

向左箭头向右箭头

选择上一个/下一个未禁用的选项卡。

向上箭头向下箭头当设置了 vertical

选择上一个/下一个未禁用的选项卡。

HomePageUp

选择第一个未禁用的选项卡。

EndPageDown

选择最后一个未禁用的选项卡。

EnterSpace 当设置了 manual

激活选中的选项卡。

所有相关的 ARIA 属性都会自动管理。

有关在 Tabs 中实现的所有可访问性功能的完整参考,请参阅 有关选项卡的 ARIA 规范

主要的 TabGroup 组件。

属性默认值描述
as模板
字符串 | 组件

TabGroup 应该渲染的元素或组件。

defaultIndex0
数字

默认选中的索引

selectedIndex
数字

如果您想将 Tabs 组件用作受控组件,则为选中的索引。

verticalfalse
布尔值

当为 true 时,TabList 的方向将为 vertical,否则将为 horizontal

manualfalse
布尔值

当为 true 时,用户只能通过键盘首先使用箭头键导航到面板,然后按 EnterSpace 来显示面板。默认情况下,当通过箭头键导航到面板时,面板会自动显示。请注意,此属性不会影响鼠标行为。

插槽属性描述
selectedIndex

数字

当前选中的索引。

事件描述
change

每当活动选项卡发生更改时调用一个函数。

属性默认值描述
asdiv
字符串 | 组件

TabList 应该渲染的元素或组件。

插槽属性描述
selectedIndex

数字

当前选中的索引。

属性默认值描述
asbutton
字符串 | 组件

Tab 应该渲染的元素或组件。

disabledfalse
布尔值

Tab 当前是否处于禁用状态。

插槽属性描述
selected

布尔值

Tab 当前是否处于选中状态。

属性默认值描述
asdiv
字符串 | 组件

TabPanels 应该渲染的元素或组件。

插槽属性描述
selectedIndex

数字

当前选中的索引。

属性默认值描述
asdiv
字符串 | 组件

TabPanel 应该渲染的元素或组件。

staticfalse
布尔值

元素是否应该忽略选中的索引。

_注意:staticunmount 不能同时使用。

unmounttrue
布尔值

元素是否应该根据选中的索引卸载或隐藏。

_注意:staticunmount 不能同时使用。

插槽属性描述
selected

布尔值

TabPanel 当前是否处于选中状态。

如果您对使用 Headless UI 和 Tailwind CSS 的预先设计的组件示例感兴趣,请查看 **Tailwind UI** — 我们精心打造的一系列精美设计且制作精良的组件。

这是一个支持我们开源项目工作的好方法,使我们能够改进这些项目并保持良好的维护。