← Back to all snippets
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.

Need help integrating this into your project?

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

Hire DigitalCodeLabs