Cómo usar componentes dinámicos en Vue para renderizar interfaces condicionales o reutilizables según el estado o los datos disponibles.
Cuando desarrollamos interfaces en Vue, nos encontramos con situaciones donde necesitamos decidir en tiempo de ejecución qué componente mostrar. En lugar de duplicar lógica o usar estructuras condicionales extensas, podemos usar componentes dinámicos. Esta característica permite renderizar un componente diferente según una variable reactiva, manteniendo el mismo punto de anclaje en el DOM.
El sistema es simple de entender y muy útil para secciones de la aplicación como formularios paso a paso, menús configurables, tabs o layouts que cambian según el rol del usuario.
Vue proporciona la etiqueta especial <component>
con el atributo :is
, que permite pasar el nombre de un componente o una referencia directamente. Así decidimos qué componente se debe mostrar.
<template> <component :is="currentComponent" /></template>
<script setup>import ComponenteA from './ComponenteA.vue'import ComponenteB from './ComponenteB.vue'
const currentComponent = ref('ComponenteA')</script>
Podemos usar una cadena de texto ('ComponenteA'
), una referencia a un componente importado o incluso un componente dinámicamente importado.
Cuando registramos los componentes directamente en el archivo, la clave que se usa para el :is
debe coincidir con el nombre del componente registrado.
<script setup>import FormLogin from './FormLogin.vue'import FormRegistro from './FormRegistro.vue'
const currentForm = ref(FormLogin)</script>
<template> <component :is="currentForm" /></template>
Esta estrategia sirve sobretodo si estamos usando imports con nombres que pueden cambiar o si estamos usando el sistema de componentes anónimos.
Podemos actualizar el componente dinámico en función de eventos, rutas o condiciones del estado global.
<template> <div> <button @click="modo = 'login'">Login</button> <button @click="modo = 'registro'">Registro</button> <component :is="modoActual" /> </div></template>
<script setup>import FormLogin from './FormLogin.vue'import FormRegistro from './FormRegistro.vue'const modo = ref('login')
const modoActual = computed(() => { return modo.value === 'login' ? FormLogin : FormRegistro})</script>
Aquí usamos una función computada para mapear el estado actual al componente correspondiente. Cada vez que se hace clic a un botón, se renderiza un componente distinto.
key
Si el componente dinámico necesita resetear su estado interno cuando cambia, debemos usar el atributo :key
. Vue recreará el componente si la clave cambia.
<component :is="componenteActual" :key="componenteActualKey" />
Este patrón es útil cuando cambiamos entre formularios, vistas o flujos que tienen su propio estado interno y no queremos que se mezclen.
También es posible cargar componentes dinámicamente solo cuando se necesitan, usando defineAsyncComponent
. Esto mejora el rendimiento en aplicaciones de mayor tamaño.
import { defineAsyncComponent } from 'vue'
const Dialogo = defineAsyncComponent(() => import('./Dialogo.vue'))
Después, lo usamos igual:
<component :is="Dialogo" />
Esto es especialmente útil cuando queremos reducir el tamaño del bundle inicial y solo cargar ciertos componentes bajo demanda.
Los componentes dinámicos en Vue nos permiten construir interfaces más flexibles y adaptables. Podemos cambiar entre vistas, flujos de usuario o secciones completas de la UI utilizando una única etiqueta <component>
y una referencia reactiva. Si combinamos esto con defineAsyncComponent
y claves reactivas, ganamos control sobre el rendimiento y el comportamiento del ciclo de vida.
Es una herramienta sencilla que se adapta bien cuando la lógica de renderizado depende de condiciones que cambian en tiempo real. Como siempre, conviene usarla cuando mejora la estructura del código.