JAVASCRIPT

Swapping Dynamic Components in Vue 3 with the `is` Attribute

Understand how to dynamically switch between different components at runtime in Vue 3 using the special `is` attribute on the `<component>` element.

// src/components/HomeView.vue
<template>
  <div>
    <h2>Home View</h2>
    <p>Welcome to the home page!</p>
  </div>
</template>

<script setup>
// Optional: Define a name for better debugging
defineOptions({ name: 'HomeView' });
</script>

// src/components/AboutView.vue
<template>
  <div>
    <h2>About View</h2>
    <p>Learn more about us here.</p>
  </div>
</template>

<script setup>
defineOptions({ name: 'AboutView' });
</script>

// src/components/ContactView.vue
<template>
  <div>
    <h2>Contact View</h2>
    <p>Get in touch with us.</p>
  </div>
</template>

<script setup>
defineOptions({ name: 'ContactView' });
</script>

// src/App.vue
<template>
  <div>
    <h1>Dynamic Component Example</h1>
    <nav>
      <button @click="activeComponent = HomeView">Home</button>
      <button @click="activeComponent = AboutView">About</button>
      <button @click="activeComponent = ContactView">Contact</button>
    </nav>
    
    <div class="component-container">
      <!-- 
        The <component> element renders the component specified by its 'is' prop.
        It's good practice to wrap dynamic components in <KeepAlive> 
        to preserve their state when switching between them.
      -->
      <KeepAlive>
        <component :is="activeComponent" />
      </KeepAlive>
    </div>
  </div>
</template>

<script setup>
import { ref, markRaw } from 'vue';
// Import components directly to use their references in `activeComponent`
import HomeView from './components/HomeView.vue';
import AboutView from './components/AboutView.vue';
import ContactView from './components/ContactView.vue';

const activeComponent = ref(HomeView); // Initialize with the HomeView component reference

// Alternatively, you could use component names as strings if they are globally registered
// or if you map them manually. When using string names with `defineAsyncComponent`,
// you would typically need to register them globally or pass them through props.
// Example using string names (less common with direct imports in setup script):
/*
const componentMap = {
  HomeView: markRaw(HomeView),
  AboutView: markRaw(AboutView),
  ContactView: markRaw(ContactView),
};
const activeComponentName = ref('HomeView');
const currentComponent = computed(() => componentMap[activeComponentName.value]);
*/

// When assigning component objects directly, it's often good practice to use markRaw
// if you don't need the component object itself to be reactive.
// However, in this simple case, `ref(HomeView)` works fine as we're just storing the reference.
// Using string names and a component map: (if you wanted to use strings instead of component objects directly)
/*
const currentTab = ref('Home');
const tabs = {
  Home: HomeView,
  About: AboutView,
  Contact: ContactView
};
const currentComponent = computed(() => tabs[currentTab.value]);
*/
</script>

<style scoped>
nav button {
  margin-right: 10px;
  padding: 8px 15px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background-color: #f9f9f9;
  cursor: pointer;
}
nav button:hover {
  background-color: #e9e9e9;
}
.component-container {
  margin-top: 20px;
  padding: 20px;
  border: 1px solid #eee;
  border-radius: 5px;
  min-height: 150px;
}
</style>
How it works: This snippet illustrates how to use dynamic components in Vue 3 with the special `<component :is="activeComponent" />` attribute. This allows you to render different components based on a reactive value (`activeComponent` in this case). When the value of `activeComponent` changes, Vue intelligently swaps out the current component for the new one. This pattern is incredibly useful for building interfaces with tabs, wizards, or highly configurable sections. The `KeepAlive` wrapper is included to optionally preserve the state of inactive dynamic components, preventing them from being unmounted and re-mounted every time you switch.

Need help integrating this into your project?

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

Hire DigitalCodeLabs