En Vue.js, los componentes dinámicos son un mecanismo que nos permite cambiar entre diferentes componentes en tiempo de ejecución.
Es decir, en lugar de utilizar un componente fijo en el código, queremos que Vue muestre un componente diferente dependiendo de la situación.
Por ejemplo, una sección que muestra que un inicio de sesión, un formulario de registro o un mensaje de bienvenida. Podrías usar un componente dinámico que cambie entre estos tres elementos cuando sea necesario.
Esto es útil en aplicaciones donde el contenido o la funcionalidad de una sección de la interfaz debe cambiar dinámicamente, y las Props y Slots no son suficientes.
Uso básico de componentes dinámicos
El uso básico de componentes dinámicos implica el uso del elemento <component>
y la propiedad is
para determinar qué componente se debe renderizar.
Vamos a verlo con un ejemplo,
<template>
<div>
<h2>Componente A</h2>
<p>Este es el Componente A.</p>
</div>
</template>
<template>
<div>
<h2>Componente B</h2>
<p>Este es el Componente B.</p>
</div>
</template>
<template>
<div>
<button @click="currentComponent = 'ComponentA'">Mostrar Componente A</button>
<button @click="currentComponent = 'ComponentB'">Mostrar Componente B</button>
<component :is="currentComponent"></component>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
const currentComponent = ref('ComponentA');
</script>
En este ejemplo:
- El componente padre (
ParentComponent
) permite cambiar entreComponentA
yComponentB
usando botones. - El elemento
<component>
con la propiedadis
renderiza el componente seleccionado.
Componentes dinámicos con props
Los componentes dinámicos también pueden recibir props, lo que permite pasar datos específicos al componente que se está renderizando.
<template>
<div>
<h2>Componente A</h2>
<p>Mensaje: {{ message }}</p>
</div>
</template>
<script setup>
defineProps({
message: String,
});
</script>
<template>
<div>
<h2>Componente B</h2>
<p>Mensaje: {{ message }}</p>
</div>
</template>
<script setup>
defineProps({
message: String,
});
</script>
<template>
<div>
<button @click="currentComponent = 'ComponentA'">Mostrar Componente A</button>
<button @click="currentComponent = 'ComponentB'">Mostrar Componente B</button>
<component :is="currentComponent" :message="message"></component>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
const currentComponent = ref('ComponentA');
const message = ref('Este es un mensaje dinámico.');
</script>
En este ejemplo:
- Los componentes
ComponentA
yComponentB
reciben una propmessage
. - El componente padre pasa la prop
message
al componente dinámico.
Componentes dinámicos con slots
Los componentes dinámicos también pueden usar slots para permitir la inserción de contenido personalizado desde el componente padre.
<template>
<div>
<h2>Componente A</h2>
<slot></slot> <!-- Slot por defecto -->
</div>
</template>
<template>
<div>
<h2>Componente B</h2>
<slot></slot> <!-- Slot por defecto -->
</div>
</template>
<template>
<div>
<button @click="currentComponent = 'ComponentA'">Mostrar Componente A</button>
<button @click="currentComponent = 'ComponentB'">Mostrar Componente B</button>
<component :is="currentComponent">
<p>Este es el contenido del slot.</p>
</component>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
const currentComponent = ref('ComponentA');
</script>
En este ejemplo:
- Los componentes
ComponentA
yComponentB
tienen un slot por defecto. - El componente padre inserta contenido en el slot del componente dinámico.
Uso de keep-alive
con componentes dinámicos
El componente <keep-alive>
permite mantener el estado de los componentes dinámicos cuando se cambia entre ellos. Esto es útil para evitar la pérdida de datos o el reinicio de animaciones.
<template>
<div>
<button @click="currentComponent = 'ComponentA'">Mostrar Componente A</button>
<button @click="currentComponent = 'ComponentB'">Mostrar Componente B</button>
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
const currentComponent = ref('ComponentA');
</script>
En este ejemplo:
- El componente
<keep-alive>
mantiene el estado deComponentA
yComponentB
cuando se cambia entre ellos.