JAVASCRIPT
Dynamically Switching Components with Vue 3's `<component :is>`
Learn how to dynamically render different components based on a variable or condition in Vue 3 using the special `<component :is>` attribute, perfect for tab interfaces.
// components/HomeTab.vue
<template>
<div class="tab-content">
<h2>Home Content</h2>
<p>This is the home page. Welcome!</p>
</div>
</template>
<script setup>
// Component specific logic
</script>
<style scoped>
.tab-content { padding: 20px; border: 1px solid #eee; background-color: #f9f9f9; }
</style>
// components/AboutTab.vue
<template>
<div class="tab-content">
<h2>About Us</h2>
<p>We are a company focused on web development solutions.</p>
</div>
</template>
<script setup>
// Component specific logic
</script>
<style scoped>
.tab-content { padding: 20px; border: 1px solid #eee; background-color: #f9f9f9; }
</style>
// components/ContactTab.vue
<template>
<div class="tab-content">
<h2>Contact Us</h2>
<p>You can reach us at [email protected].</p>
</div>
</template>
<script setup>
// Component specific logic
</script>
<style scoped>
.tab-content { padding: 20px; border: 1px solid #eee; background-color: #f9f9f9; }
</style>
// App.vue
<template>
<div>
<h1>Dynamic Tab Example</h1>
<div class="tab-navigation">
<button :class="{ active: currentTab === 'HomeTab' }" @click="currentTab = 'HomeTab'">Home</button>
<button :class="{ active: currentTab === 'AboutTab' }" @click="currentTab = 'AboutTab'">About</button>
<button :class="{ active: currentTab === 'ContactTab' }" @click="currentTab = 'ContactTab'">Contact</button>
</div>
<div class="tab-container">
<!-- The magic happens here: dynamically rendering components -->
<component :is="currentTabComponent"></component>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import HomeTab from './components/HomeTab.vue';
import AboutTab from './components/AboutTab.vue';
import ContactTab from './components/ContactTab.vue';
const currentTab = ref('HomeTab'); // Holds the name of the current tab/component
const tabs = {
HomeTab,
AboutTab,
ContactTab
};
const currentTabComponent = computed(() => {
return tabs[currentTab.value];
});
</script>
<style scoped>
.tab-navigation button {
padding: 10px 15px;
margin-right: 5px;
border: 1px solid #ccc;
background-color: #f0f0f0;
cursor: pointer;
border-radius: 5px 5px 0 0;
border-bottom: none;
}
.tab-navigation button.active {
background-color: #fff;
border-color: #333;
color: #333;
font-weight: bold;
}
.tab-container {
margin-top: -1px; /* Overlap border */
}
</style>
How it works: This snippet demonstrates how to use Vue 3's special `<component>` element with the `:is` attribute to dynamically render different components. By binding `:is` to a reactive property (`currentTabComponent` in this case), we can switch which component is rendered at runtime. The `currentTabComponent` is a computed property that resolves to one of the imported component objects based on the `currentTab` string. This pattern is incredibly useful for building dynamic UIs like tabbed interfaces, wizards, or dashboards where content needs to change without full page reloads.