How to Create Tabs in Vue: Simple Tab Component Example
To create tabs in Vue, use a reactive variable to track the active tab and conditionally render content with
v-if. Use @click events on tab buttons to update the active tab state and show the corresponding content.Syntax
Use a reactive variable (like activeTab) to store the current tab's name or index. Use @click on tab buttons to change activeTab. Use v-if or v-show to display content for the active tab only.
This pattern keeps the UI simple and reactive.
vue
<template>
<div>
<button @click="activeTab = 'tab1'">Tab 1</button>
<button @click="activeTab = 'tab2'">Tab 2</button>
<div v-if="activeTab === 'tab1'">Content for Tab 1</div>
<div v-if="activeTab === 'tab2'">Content for Tab 2</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const activeTab = ref('tab1')
</script>Output
Two buttons labeled 'Tab 1' and 'Tab 2'. Clicking a button shows the content for that tab below the buttons.
Example
This example shows a simple tabs component with three tabs. Clicking a tab changes the displayed content. The active tab button is styled differently.
vue
<template>
<div>
<nav>
<button
v-for="tab in tabs"
:key="tab"
@click="activeTab = tab"
:class="{ active: activeTab === tab }"
:aria-selected="activeTab === tab"
role="tab"
tabindex="0"
>
{{ tab }}
</button>
</nav>
<section role="tabpanel">
<p v-if="activeTab === 'Home'">Welcome to the Home tab content.</p>
<p v-if="activeTab === 'Profile'">Here is your Profile information.</p>
<p v-if="activeTab === 'Settings'">Adjust your Settings here.</p>
</section>
</div>
</template>
<script setup>
import { ref } from 'vue'
const tabs = ['Home', 'Profile', 'Settings']
const activeTab = ref('Home')
</script>
<style scoped>
button {
padding: 0.5rem 1rem;
margin-right: 0.5rem;
border: none;
background: #eee;
cursor: pointer;
font-weight: 600;
}
button.active {
background: #42b983;
color: white;
}
button:focus {
outline: 2px solid #42b983;
}
</style>Output
Three buttons labeled 'Home', 'Profile', and 'Settings'. Clicking each button highlights it and shows its content below.
Common Pitfalls
Not using reactive state: If you use a normal variable instead of ref, Vue won't update the UI when the tab changes.
Using v-show incorrectly: v-show hides content with CSS but keeps it in the DOM, which may cause performance issues with many tabs.
Missing accessibility roles: Tabs should have role="tab" and role="tabpanel" for screen readers.
vue
<!-- Wrong: non-reactive variable --> <script setup> let activeTab = 'tab1' // Vue won't react to this change </script> <!-- Right: reactive ref --> <script setup> import { ref } from 'vue' const activeTab = ref('tab1') </script>
Quick Reference
- Use
refto track active tab state. - Use
@clickto update active tab. - Use
v-iforv-showto conditionally render tab content. - Style active tab button for clarity.
- Add ARIA roles for accessibility.
Key Takeaways
Use a reactive variable with ref() to track the active tab in Vue.
Update the active tab state with @click on tab buttons to switch content.
Use v-if or v-show to conditionally display content for the active tab.
Add ARIA roles like role="tab" and role="tabpanel" for better accessibility.
Style the active tab button to clearly show which tab is selected.