Usage
The Tabs component allows users to switch between different views or sections of content. It supports icons, avatars, badges, and various orientations.
Basic Example
<template>
<UTabs :items="items" />
</template>
<script setup>
const items = [
{ label: 'Account', content: 'Make changes to your account here.' },
{ label: 'Password', content: 'Change your password here.' },
{ label: 'Settings', content: 'Manage your settings here.' }
]
</script>
With Icons
<template>
<UTabs :items="items" />
</template>
<script setup>
const items = [
{ label: 'Home', icon: 'i-lucide-home', content: 'Welcome home!' },
{ label: 'Settings', icon: 'i-lucide-settings', content: 'Adjust your settings.' },
{ label: 'Profile', icon: 'i-lucide-user', content: 'View your profile.' }
]
</script>
With Badges
<template>
<UTabs :items="items" />
</template>
<script setup>
const items = [
{ label: 'Inbox', badge: 5, content: 'You have 5 new messages.' },
{ label: 'Sent', badge: 0, content: 'No sent messages.' },
{ label: 'Drafts', badge: { label: '3', color: 'primary' }, content: '3 drafts saved.' }
]
</script>
Vertical Orientation
<template>
<UTabs :items="items" orientation="vertical" />
</template>
<script setup>
const items = [
{ label: 'Account', content: 'Make changes to your account here.' },
{ label: 'Password', content: 'Change your password here.' },
{ label: 'Settings', content: 'Manage your settings here.' }
]
</script>
Different Variants
<template>
<div class="space-y-4">
<UTabs :items="items" variant="pill" />
<UTabs :items="items" variant="link" />
</div>
</template>
<script setup>
const items = [
{ label: 'Tab 1', content: 'Content 1' },
{ label: 'Tab 2', content: 'Content 2' },
{ label: 'Tab 3', content: 'Content 3' }
]
</script>
Controlled State
<template>
<div>
<UTabs v-model="selectedTab" :items="items" />
<p class="mt-4">Current tab: {{ selectedTab }}</p>
</div>
</template>
<script setup>
const selectedTab = ref('1')
const items = [
{ label: 'First', value: '1', content: 'First tab content' },
{ label: 'Second', value: '2', content: 'Second tab content' },
{ label: 'Third', value: '3', content: 'Third tab content' }
]
</script>
Disabled Tabs
<template>
<UTabs :items="items" />
</template>
<script setup>
const items = [
{ label: 'Available', content: 'This tab is available.' },
{ label: 'Disabled', content: 'This content cannot be accessed.', disabled: true },
{ label: 'Also Available', content: 'This tab is also available.' }
]
</script>
Without Content
<template>
<UTabs v-model="selectedTab" :items="items" :content="false" />
<!-- Custom content outside tabs -->
<div class="mt-4">
<div v-if="selectedTab === '0'">Custom content for tab 1</div>
<div v-else-if="selectedTab === '1'">Custom content for tab 2</div>
<div v-else>Custom content for tab 3</div>
</div>
</template>
<script setup>
const selectedTab = ref('0')
const items = [
{ label: 'Tab 1' },
{ label: 'Tab 2' },
{ label: 'Tab 3' }
]
</script>
API
Props
Array of tab items to display.
The controlled value of the active tab (v-model).
defaultValue
string | number
default:"'0'"
The default active tab value when uncontrolled.
The element or component this component should render as.
color
string
default:"'primary'"
The color theme of the tabs.
The visual variant of the tabs. Options: pill, link.
The size of the tabs. Options: xs, sm, md, lg, xl.
orientation
string
default:"'horizontal'"
The orientation of the tabs. Options: horizontal, vertical.
Whether to render the content panels. Set to false to manage content externally.
How tabs are activated. Options: automatic, manual.
Whether to unmount inactive tab content from the DOM.
The key used to get the value from the item.
The key used to get the label from the item.
Additional CSS classes to apply to the root element.
Custom UI configuration for slots.
TabsItem
The text label for the tab.
A unique value for the tab item. Defaults to the index.
An Iconify icon name to display before the label.
Avatar configuration to display before the label.
badge
string | number | BadgeProps
Display a badge on the tab. Can be a simple value or full badge configuration.
The content to display in the tab panel.
Custom slot name for this tab’s content.
Whether the tab is disabled.
Additional CSS classes for the tab.
Custom UI configuration for this tab’s slots.
Emits
update:modelValue
(value: string | number) => void
Emitted when the active tab changes.
Slots
default
Customize the tab label.
<template>
<UTabs :items="items">
<template #default="{ item, index }">
<span class="uppercase">{{ item.label }}</span>
</template>
</UTabs>
</template>
leading
Customize the leading icon or avatar for all tabs.
<template>
<UTabs :items="items">
<template #leading="{ item, index, ui }">
<UIcon :name="item.icon" class="text-primary" />
</template>
</UTabs>
</template>
trailing
Customize the trailing badge or add custom trailing content.
<template>
<UTabs :items="items">
<template #trailing="{ item, index, ui }">
<UBadge v-if="item.count" :label="item.count" />
</template>
</UTabs>
</template>
content
Customize the content panel for all tabs.
<template>
<UTabs :items="items">
<template #content="{ item, index, ui }">
<div class="p-4">
<h3>{{ item.label }}</h3>
<p>{{ item.content }}</p>
</div>
</template>
</UTabs>
</template>
list-leading
Add content before the tab list.
<template>
<UTabs :items="items">
<template #list-leading>
<UButton icon="i-lucide-plus" size="xs" />
</template>
</UTabs>
</template>
list-trailing
Add content after the tab list.
<template>
<UTabs :items="items">
<template #list-trailing>
<UButton icon="i-lucide-settings" size="xs" />
</template>
</UTabs>
</template>
Dynamic Slots
You can use dynamic slots based on the slot property of items:
<template>
<UTabs :items="items">
<template #special-content="{ item, index, ui }">
<div class="special-content">
This is special content!
</div>
</template>
</UTabs>
</template>
<script setup>
const items = [
{ label: 'Normal', content: 'Normal content' },
{ label: 'Special', slot: 'special' }
]
</script>