JAVASCRIPT
Building Dynamic Tabbed Interfaces with Vue 3 Components
Implement flexible tabbed navigation or content switching in Vue 3 using dynamic components and the `is` attribute, allowing for conditional rendering of components.
<!-- src/components/TabA.vue -->
<template>
<div class="tab-content">
<h2>Content for Tab A</h2>
<p>This is the first tab's content. It's unique!</p>
</div>
</template>
<script setup></script>
<style scoped> .tab-content { border: 1px solid #ccc; padding: 20px; background-color: #f9f9f9; } </style>
<!-- src/components/TabB.vue -->
<template>
<div class="tab-content">
<h2>Content for Tab B</h2>
<p>Hello from the second tab!</p>
<button>Click Me</button>
</div>
</template>
<script setup></script>
<style scoped> .tab-content { border: 1px solid #ccc; padding: 20px; background-color: #f9f9f9; } </style>
<!-- src/components/TabC.vue -->
<template>
<div class="tab-content">
<h2>Content for Tab C</h2>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</template>
<script setup></script>
<style scoped> .tab-content { border: 1px solid #ccc; padding: 20px; background-color: #f9f9f9; } </style>
<!-- src/App.vue (Tabbed Interface Component) -->
<template>
<div class="tab-container">
<div class="tabs">
<button
v-for="tab in tabs"
:key="tab.component"
:class="{ active: currentTab === tab.component }"
@click="currentTab = tab.component"
>
{{ tab.name }}
</button>
</div>
<div class="tab-panel">
<component :is="currentTabComponent"></component>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import TabA from './components/TabA.vue';
import TabB from './components/TabB.vue';
import TabC from './components/TabC.vue';
const currentTab = ref('TabA'); // Initial active tab
const tabs = [
{ name: 'Tab A', component: 'TabA' },
{ name: 'Tab B', component: 'TabB' },
{ name: 'Tab C', component: 'TabC' }
];
// Map string names to actual component references
const tabComponents = {
TabA,
TabB,
TabC
};
const currentTabComponent = computed(() => tabComponents[currentTab.value]);
</script>
<style scoped>
.tab-container {
font-family: Arial, sans-serif;
max-width: 600px;
margin: 20px auto;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
}
.tabs {
display: flex;
border-bottom: 1px solid #ddd;
}
.tabs button {
flex-grow: 1;
padding: 15px 20px;
border: none;
background-color: #f0f0f0;
cursor: pointer;
font-size: 1em;
transition: background-color 0.3s ease;
}
.tabs button:hover {
background-color: #e0e0e0;
}
.tabs button.active {
background-color: #fff;
border-bottom: 2px solid #007bff;
color: #007bff;
}
.tab-panel {
padding: 20px;
}
</style>
How it works: This snippet demonstrates creating a dynamic tabbed interface using Vue 3's `<component :is="...">` feature. By binding the `is` attribute to `currentTabComponent`, Vue dynamically renders the component corresponding to the currently selected tab. The `currentTabComponent` is a computed property that maps a string name (e.g., 'TabA') to the actual imported component reference. This allows for flexible and efficient rendering of different components based on application state without manually mounting or unmounting them.