The VTabs component provides a tabbed interface for organizing content into separate views. It features smooth transitions, responsive behavior, and integrates with VTabsWindow for content panels.
Basic Usage
<template>
<v-tabs v-model="tab">
<v-tab value="one">Tab 1</v-tab>
<v-tab value="two">Tab 2</v-tab>
<v-tab value="three">Tab 3</v-tab>
</v-tabs>
<v-tabs-window v-model="tab">
<v-tabs-window-item value="one">
Content for Tab 1
</v-tabs-window-item>
<v-tabs-window-item value="two">
Content for Tab 2
</v-tabs-window-item>
<v-tabs-window-item value="three">
Content for Tab 3
</v-tabs-window-item>
</v-tabs-window>
</template>
<script setup>
import { ref } from 'vue'
const tab = ref('one')
</script>
Currently selected tab value. Use with v-model.
Array of tab items. Each item can be a string, number, or object with text and value properties.
alignTabs
'start' | 'title' | 'center' | 'end'
default:"'start'"
Alignment of tabs within the container.
Color applied to the active tab and slider.
Background color of the tabs bar.
Color of the selection slider indicator.
Hides the slider indicator under the active tab.
Makes tabs have equal width with a maximum of 300px each.
Makes tabs expand to fill available horizontal space.
Stacks tab icon and text vertically.
Applies inset styling to the slider.
Padding for inset slider.
Border radius for inset slider.
direction
'horizontal' | 'vertical'
default:"'horizontal'"
Orientation of the tabs.
density
'default' | 'comfortable' | 'compact'
Adjusts the vertical spacing of tabs.
selectedClass
string
default:"'v-tab-item--selected'"
CSS class applied to the selected tab.
sliderTransition
'shift' | 'grow' | 'fade'
Animation style for the slider when changing tabs.
Duration of the slider transition animation in milliseconds.
Adds spacing between tabs.
Shows navigation arrows when tabs overflow.
mandatory
boolean | 'force'
default:"'force'"
Forces at least one tab to be selected.
HTML tag for the root element.
Emitted when the selected tab changes.
Content for the tabs. Usually contains VTab components.
Slot to customize tab rendering when using items prop.
Slot to customize window item content when using items prop.
Additional content in the tabs window.
Slot to customize the previous navigation arrow.
Slot to customize the next navigation arrow.
Named slot for specific tab content.
Named slot for specific window item content.
VTab Props
Value used when tab is selected.
Icon displayed in the tab.
Navigation Patterns
Items-based Tabs
<template>
<v-tabs v-model="tab" :items="items">
<template #item.tab1="{ item }">
<div>Content for {{ item.text }}</div>
</template>
<template #item.tab2="{ item }">
<div>Content for {{ item.text }}</div>
</template>
</v-tabs>
</template>
<script setup>
import { ref } from 'vue'
const tab = ref('tab1')
const items = [
{ text: 'Tab 1', value: 'tab1' },
{ text: 'Tab 2', value: 'tab2' }
]
</script>
Centered Tabs
<template>
<v-tabs v-model="tab" align-tabs="center">
<v-tab value="one">Tab 1</v-tab>
<v-tab value="two">Tab 2</v-tab>
</v-tabs>
</template>
Fixed Width Tabs
<template>
<v-tabs v-model="tab" fixed-tabs>
<v-tab value="one">Tab 1</v-tab>
<v-tab value="two">Tab 2</v-tab>
<v-tab value="three">Tab 3</v-tab>
</v-tabs>
</template>
Growing Tabs
<template>
<v-tabs v-model="tab" grow>
<v-tab value="one">Tab 1</v-tab>
<v-tab value="two">Tab 2</v-tab>
</v-tabs>
</template>
Vertical Tabs
<template>
<v-tabs v-model="tab" direction="vertical">
<v-tab value="one">Tab 1</v-tab>
<v-tab value="two">Tab 2</v-tab>
</v-tabs>
</template>
Stacked Tabs with Icons
<template>
<v-tabs v-model="tab" stacked>
<v-tab value="one" icon="mdi-home">Home</v-tab>
<v-tab value="two" icon="mdi-account">Profile</v-tab>
<v-tab value="three" icon="mdi-cog">Settings</v-tab>
</v-tabs>
</template>
Examples
Custom Slider Color
<template>
<v-tabs
v-model="tab"
color="primary"
slider-color="yellow"
>
<v-tab value="one">Tab 1</v-tab>
<v-tab value="two">Tab 2</v-tab>
</v-tabs>
</template>
Inset Slider
<template>
<v-tabs
v-model="tab"
inset
slider-color="primary"
bg-color="grey-lighten-3"
>
<v-tab value="one">Tab 1</v-tab>
<v-tab value="two">Tab 2</v-tab>
</v-tabs>
</template>
Router Integration
<template>
<v-tabs v-model="tab">
<v-tab value="home" to="/">Home</v-tab>
<v-tab value="about" to="/about">About</v-tab>
<v-tab value="contact" to="/contact">Contact</v-tab>
</v-tabs>
</template>
Disabled Tab
<template>
<v-tabs v-model="tab">
<v-tab value="one">Tab 1</v-tab>
<v-tab value="two" disabled>Tab 2</v-tab>
<v-tab value="three">Tab 3</v-tab>
</v-tabs>
</template>
Custom Transition
<template>
<v-tabs
v-model="tab"
slider-transition="grow"
:slider-transition-duration="400"
>
<v-tab value="one">Tab 1</v-tab>
<v-tab value="two">Tab 2</v-tab>
</v-tabs>
</template>
Dynamic Tabs
<template>
<v-tabs v-model="tab">
<v-tab
v-for="item in tabs"
:key="item.value"
:value="item.value"
>
{{ item.text }}
</v-tab>
</v-tabs>
<v-tabs-window v-model="tab">
<v-tabs-window-item
v-for="item in tabs"
:key="item.value"
:value="item.value"
>
{{ item.content }}
</v-tabs-window-item>
</v-tabs-window>
</template>
<script setup>
import { ref } from 'vue'
const tab = ref('tab1')
const tabs = [
{ text: 'Tab 1', value: 'tab1', content: 'Content 1' },
{ text: 'Tab 2', value: 'tab2', content: 'Content 2' },
{ text: 'Tab 3', value: 'tab3', content: 'Content 3' }
]
</script>
Accessibility
- Uses
role="tablist" on the tabs container
- Uses
role="tab" on individual tabs
- Sets
aria-selected on the active tab
- Manages
tabindex for keyboard navigation
- Tab content panels should use
role="tabpanel"
Slider Transitions
Shift (Default)
The slider smoothly shifts from the previous tab to the new tab, scaling dynamically.
The slider scales from 0 to full size at the new tab position.
The slider fades in at the new tab position.
Transition durations:
- Shift: 225ms (default)
- Grow: 350ms (default)
- Fade: 400ms (default)