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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs