Los slots en Vue te permiten crear componentes flexibles que actúan como contenedores reutilizables, donde puedes inyectar contenido dinámico desde el componente padre. Si trabajas con Vue, dominar slots y named slots te ayudará a construir layouts y composiciones más limpias, sin duplicar lógica ni estilos.
Esta guía te muestra cómo declararlos, cuándo usar cada tipo y cómo validar si un slot fue recibido usando useSlots.
¿Qué es un slot en Vue y para qué sirve?
Un slot es un espacio vacío dentro de un componente, una especie de placeholder o boilerplate, donde colocas piezas de código u otros componentes. Piensa en él como un hueco reservado que el componente padre rellena con lo que necesite.
¿Qué es un slot en Vue? Es una etiqueta <slot /> que define dónde se renderizará el contenido hijo que envuelve a un componente. Funciona como un contenedor flexible para reutilizar estructuras visuales.
En el proyecto de ejemplo existe un componente GameLayout que debe envolver todas las cards del juego. Sin slot, las cards se renderizan fuera del layout y pierden estilos como el display: grid con gap: 2rem definido en el componente.
¿Cómo se declara un slot por defecto?
Se declara con la etiqueta <slot /> dentro del template del componente. Todo lo que pongas como hijo de ese componente al usarlo se renderizará justo donde está esa etiqueta.
vue
<!-- GameLayout.vue -->
<template>
<div class="game-layout">
<slot />
</div>
</template>
Luego, en el componente padre, importas y envuelves el contenido:
vue
<script setup>
import GameLayout from './GameLayout.vue'
</script>
<template>
<GameLayout>
<GameCard v-for="game in games" :key="game.id" :game="game" />
</GameLayout>
</template>
Un detalle importante: si el layout no aplica los estilos como esperas, revisa propiedades como max-width. En el proyecto se ajustó a 90% para alinear correctamente las cards.
¿Cómo funcionan los named slots y cuándo usarlos?
El slot genérico siempre renderiza el contenido en el mismo lugar. Pero cuando necesitas pasar varios bloques opcionales, como un título personalizado, un header o un footer, los named slots te dan ese control.
Para declarar un named slot dentro del componente, usas el atributo name:
vue
<!-- GameLayout.vue -->
<template>
<div class="game-layout">
<slot name="title" />
<slot />
</div>
</template>
Y en el padre, usas la sintaxis <template #nombre> para apuntar a ese slot específico:
vue
<GameLayout>
<template #title>
<h3>Juegos actualizados</h3>
</template>
<GameCard v-for="game in games" :key="game.id" :game="game" />
</GameLayout>
¿Cuál es la diferencia entre slot por defecto y named slot? El slot por defecto recibe todo el contenido sin nombre y suele usarse como wrapper. El named slot recibe contenido específico marcado con #nombre, ideal para headers, footers o títulos opcionales.
Un detalle clave: la etiqueta <slot> no debe ir dentro de un <template> cuando la declaras en el componente hijo. Va directamente en el markup. Si la envuelves en <template>, no se renderiza.
¿Cómo detectar si un slot fue pasado con useSlots?
Vue ofrece el composable useSlots, que te devuelve un objeto con todos los slots recibidos. Así puedes condicionar qué renderizar según lo que el padre haya enviado.
vue
<script setup>
import { useSlots } from 'vue'
const slots = useSlots()
console.log(slots) // { title: fn, default: fn }
</script>
<template>
<h2 v-if="slots.title === undefined">Recent Games</h2>
<slot name="title" />
<slot />
</template>
Cada propiedad del objeto slots es una función, porque representa un componente de Vue. Si el slot no fue enviado, su valor es undefined. Con un simple v-if decides si mostrar un valor por defecto, como Recent Games, o el contenido custom enviado por el padre.
¿Cuándo conviene usar cada tipo de slot?
La elección entre uno u otro depende del nivel de personalización que necesites en tu componente.
- Usa el slot por defecto cuando quieras crear un wrapper que envuelva una serie de componentes hijos sin diferenciarlos. Es la opción más sencilla para layouts generales.
- Usa named slots cuando tu componente tenga zonas específicas como header, footer, título o sidebar, y quieras cambiarlas según la lógica del padre.
- Combina ambos cuando un layout necesite tanto un área principal flexible como secciones nombradas opcionales.
Los slots son una pieza fundamental de la composición en Vue, te permiten construir componentes verdaderamente reutilizables sin acoplarlos a un contenido fijo. Cuéntame en los comentarios qué layouts estás construyendo con slots y si te ha tocado refactorizar componentes legacy para introducirlos.