选项卡
轻松创建可访问、完全可定制的选项卡界面,具有强大的焦点管理和键盘导航支持。
要开始,请通过 npm 安装无状态 UI
npm install @headlessui/vue
选项卡是使用 TabGroup
、TabList
、Tab
、TabPanels
和 TabPanel
组件构建的。默认情况下,第一个选项卡处于选中状态,单击任何选项卡或使用键盘选择它将激活相应的面板。
<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>
默认情况下,当用户使用箭头键浏览它们时,选项卡会自动选中。
如果您不想在用户按下 Enter
或 Space
之前更改当前选项卡,请在 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
组件获得焦点时,所有交互都适用。
命令 | 描述 |
向左箭头 和 向右箭头 | 选择上一个/下一个未禁用的选项卡。 |
向上箭头 和 向下箭头当设置了 | 选择上一个/下一个未禁用的选项卡。 |
Home 或 PageUp | 选择第一个未禁用的选项卡。 |
End 或 PageDown | 选择最后一个未禁用的选项卡。 |
Enter 或 Space 当设置了 | 激活选中的选项卡。 |
属性 | 默认值 | 描述 |
as | 模板 | 字符串 | 组件
|
defaultIndex | 0 | 数字 默认选中的索引 |
selectedIndex | — | 数字 如果您想将 Tabs 组件用作受控组件,则为选中的索引。 |
vertical | false | 布尔值 当为 true 时, |
manual | false | 布尔值 当为 true 时,用户只能通过键盘首先使用箭头键导航到面板,然后按 |
插槽属性 | 描述 |
selectedIndex |
当前选中的索引。 |
事件 | 描述 |
change | 每当活动选项卡发生更改时调用一个函数。 |
属性 | 默认值 | 描述 |
as | div | 字符串 | 组件
|
插槽属性 | 描述 |
selectedIndex |
当前选中的索引。 |
属性 | 默认值 | 描述 |
as | button | 字符串 | 组件
|
disabled | false | 布尔值
|
插槽属性 | 描述 |
selected |
|
属性 | 默认值 | 描述 |
as | div | 字符串 | 组件
|
插槽属性 | 描述 |
selectedIndex |
当前选中的索引。 |
属性 | 默认值 | 描述 |
as | div | 字符串 | 组件
|
static | false | 布尔值 元素是否应该忽略选中的索引。 _注意: |
unmount | true | 布尔值 元素是否应该根据选中的索引卸载或隐藏。 _注意: |
插槽属性 | 描述 |
selected |
|