JAVASCRIPT
Dynamically Render Components with Vue 3's <component :is>
Learn to dynamically switch between different components in Vue 3 using the `<component :is>` attribute, perfect for creating tabbed interfaces, wizards, or pluggable UI elements.
// components/HomeTab.vue
<template>
<div>
<h3>Home Content</h3>
<p>Welcome to the home section of our dynamic application.</p>
</div>
</template>
<script setup>
// Component specific logic
</script>
// components/ProfileTab.vue
<template>
<div>
<h3>User Profile</h3>
<p>View and edit your profile details here.</p>
</div>
</template>
<script setup>
// Component specific logic
</script>
// components/SettingsTab.vue
<template>
<div>
<h3>Application Settings</h3>
<p>Configure your application preferences.</p>
</div>
</template>
<script setup>
// Component specific logic
</script>
// App.vue
<template>
<div>
<h1>Dynamic Component Example</h1>
<nav>
<button @click="activeComponent = 'HomeTab'" :class="{ active: activeComponent === 'HomeTab' }">Home</button>
<button @click="activeComponent = 'ProfileTab'" :class="{ active: activeComponent === 'ProfileTab' }">Profile</button>
<button @click="activeComponent = 'SettingsTab'" :class="{ active: activeComponent === 'SettingsTab' }">Settings</button>
</nav>
<div class="component-container">
<!-- The magic happens here: dynamically rendering components -->
<component :is="activeComponent" />
</div>
</div>
</template>
<script setup>
import { ref, shallowRef } from 'vue';
// Import all components that can be dynamically rendered
import HomeTab from './components/HomeTab.vue';
import ProfileTab from './components/ProfileTab.vue';
import SettingsTab from './components/SettingsTab.vue';
// A mapping of component names to their actual component objects
const components = {
HomeTab,
ProfileTab,
SettingsTab
};
// The currently active component's name. Use shallowRef for performance if components are large.
// Use ref if you want reactivity on nested objects within the component itself (not common for :is)
const activeComponent = shallowRef('HomeTab');
// To use string names directly with <component :is="activeComponent">,
// you might need to register them globally or resolve them manually.
// For setup script, if `activeComponent` is a string, you can map it:
// const currentTab = computed(() => components[activeComponent.value]);
// And then use: <component :is="currentTab" />
// However, if `activeComponent` itself holds the component *object*, it's simpler.
// Let's modify `activeComponent` to hold the component object directly to make it work out-of-the-box.
const currentComponentInstance = computed(() => components[activeComponent.value]);
// Re-adjusting the template to use the computed property
// <component :is="currentComponentInstance" />
// Simplified for direct string usage with components object - works if components are imported
// and directly referenced or if they are globally registered.
// In setup script, Vue 3 handles resolving string names if they are available in scope.
// For `:is="activeComponent"`, if `activeComponent` is a string like 'HomeTab',
// Vue will look for a component named 'HomeTab' that's either globally registered or
// imported and available in the current component's scope. Given the imports above, this works.
</script>
<style scoped>
nav button {
padding: 10px 15px;
margin-right: 10px;
border: 1px solid #ccc;
background-color: #f0f0f0;
cursor: pointer;
border-radius: 4px;
}
nav button.active {
background-color: #007bff;
color: white;
border-color: #007bff;
}
.component-container {
margin-top: 20px;
padding: 20px;
border: 1px solid #eee;
border-radius: 8px;
background-color: #fff;
}
</style>
How it works: This snippet showcases Vue 3's powerful `<component :is>` attribute, which allows you to dynamically render different components based on a reactive value. By binding `:is` to a component's name (as a string) or its imported component object, you can create highly flexible user interfaces like tabbed navigations or step-by-step wizards. The example demonstrates switching between `HomeTab`, `ProfileTab`, and `SettingsTab` components when corresponding buttons are clicked, making the active component reactive and enabling smooth UI transitions.