JAVASCRIPT
Rendering Dynamic Components with Vue 3's `<component :is='...'>`
Discover how to dynamically render components in Vue 3 using the special `<component :is='...' />` attribute, enabling flexible and modular UI development.
// ChildComponentA.vue
<template>
<div style="border: 1px solid blue; padding: 10px; margin-bottom: 10px;">
<h3>Component A</h3>
<p>This is content from Component A. Prop message: {{ message }}</p>
<button @click="$emit('action-a', 'Hello from A!')">Action A</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
defineProps({
message: String,
});
defineEmits(['action-a']);
</script>
// ChildComponentB.vue
<template>
<div style="border: 1px solid green; padding: 10px; margin-bottom: 10px;">
<h3>Component B</h3>
<p>This is content from Component B. Prop count: {{ count }}</p>
<button @click="$emit('action-b', count * 2)">Action B</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
defineProps({
count: Number,
});
defineEmits(['action-b']);
</script>
// ParentComponent.vue
<template>
<div>
<h2>Dynamic Component Example</h2>
<button @click="toggleComponent">Toggle Component</button>
<component
:is="currentComponent"
:message="'Dynamic Message'"
:count="10"
@action-a="handleActionA"
@action-b="handleActionB"
></component>
<p>Last action result: {{ lastActionResult }}</p>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import ChildComponentA from './ChildComponentA.vue';
import ChildComponentB from './ChildComponentB.vue';
const activeComponent = ref('A');
const lastActionResult = ref('');
const currentComponent = computed(() => {
return activeComponent.value === 'A' ? ChildComponentA : ChildComponentB;
});
function toggleComponent() {
activeComponent.value = activeComponent.value === 'A' ? 'B' : 'A';
lastActionResult.value = '';
}
function handleActionA(payload) {
lastActionResult.value = `Component A emitted: ${payload}`;
}
function handleActionB(payload) {
lastActionResult.value = `Component B emitted: ${payload}`;
}
</script>
How it works: Vue 3's `<component :is='...' />` attribute allows you to dynamically render components based on a reactive value. In this snippet, `ParentComponent.vue` uses a `computed` property `currentComponent` to switch between `ChildComponentA` and `ChildComponentB`. The `is` attribute can bind to either a component's registered name (as a string) or, more powerfully with the Composition API and `<script setup>`, directly to the imported component object. Props and event listeners can be passed universally to the dynamic component, making it a flexible solution for tabbed interfaces, wizards, or highly configurable dashboards.