Newsletter para devsEntra
Aprende Astro framework

Slots en componentes

Nos hemos dejado por el camino un fragmento que no es personalizable en nuestro componente Hero: la descripción en texto largo.

Ahora mismo es un texto dentro de una etiqueta <p> y no es configurable.

¿Podríamos pasarlo con un prop?

En informática todo es posible, pero siempre hay un camino más corto.

El fantástico mundo de los slots

Entremos en el mundo de los slots (ranuras, en inglés) que están pensados precisamente para este caso.

Volvemos a Hero.astro y lo dejamos así:

/src/components/Hero.astro
Copy

_31
---
_31
interface Props {
_31
title: string;
_31
imageUrl: string;
_31
buttonText?: string;
_31
buttonLink?: string;
_31
}
_31
const { title, imageUrl, buttonText, buttonLink } = Astro.props;
_31
---
_31
_31
<div class="row flex-lg-row-reverse align-items-center g-5 py-5">
_31
<div class="col-10 col-sm-8 col-lg-6">
_31
<img
_31
src={imageUrl}
_31
class="d-block mx-lg-auto img-fluid"
_31
alt="Flamante página de Astro"
_31
width="700"
_31
height="500"
_31
loading="lazy"
_31
/>
_31
</div>
_31
<div class="col-lg-6">
_31
<h1 class="display-5 fw-bold lh-1 mb-3">{title}</h1>
_31
<slot />
_31
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
_31
<a href={buttonLink} class="btn btn-primary btn-lg px-4 me-md-2"
_31
>{buttonText}</a
_31
>
_31
</div>
_31
</div>
_31
</div>

🔍 slot es un componente propio de Astro que nos va a permitir pasar desde el padre al componente hijo etiquetas de HTML.

Fíjate ahora en el cambio en index.astro

/src/pages/index.astro
Copy

_13
<Hero
_13
title="Mi primera Astro web"
_13
imageUrl="https://placekitten.com/g/500/400"
_13
buttonText="Leer más"
_13
buttonLink="/about"
_13
>
_13
<p class="lead">
_13
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
_13
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
_13
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
_13
aliquip ex ea commodo consequat.
_13
</p>
_13
</Hero>

👀 Ves como abrimos y cerramos <Hero> y encerrado entre las etiquetas está el HTML de la descripción. El componente trasladará ese <p> al lugar donde está definido <slot> en el componente

¡Funciona igual que el HTML!

🔍 Los componentes de Astro permiten más de un slot por componente, pero no lo veremos en el bootcamp.

Slot por defecto

Siempre es bueno considerar valores por defecto si así lo creemos conveniente. Seguramente nos ahorre escribir menos código en la siguiente iteración.

⚡️ Recuerda que tenemos importado Hero.astro tanto en index.astro como en about.astro.

Modificamos el componente de nuevo:

/src/components/Hero.astro
Copy

_38
---
_38
interface Props {
_38
title: string;
_38
imageUrl: string;
_38
buttonText?: string;
_38
buttonLink?: string;
_38
}
_38
const { title, imageUrl, buttonText, buttonLink } = Astro.props;
_38
---
_38
_38
<div class="row flex-lg-row-reverse align-items-center g-5 py-5">
_38
<div class="col-10 col-sm-8 col-lg-6">
_38
<img
_38
src={imageUrl}
_38
class="d-block mx-lg-auto img-fluid"
_38
alt="Flamante página de Astro"
_38
width="700"
_38
height="500"
_38
loading="lazy"
_38
/>
_38
</div>
_38
<div class="col-lg-6">
_38
<h1 class="display-5 fw-bold lh-1 mb-3">{title}</h1>
_38
<slot>
_38
<p class="lead">
_38
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
_38
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
_38
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
_38
aliquip ex ea commodo consequat.
_38
</p>
_38
</slot>
_38
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
_38
<a href={buttonLink} class="btn btn-primary btn-lg px-4 me-md-2"
_38
>{buttonText}</a
_38
>
_38
</div>
_38
</div>
_38
</div>

👀 Usamos el mismo procedimiento que antes pero dentro del slot. Ese será ahora el valor por defecto.

Vamos a index.astro y lo simplificamos de esta manera.

/src/pages/index.astro
Copy

_16
---
_16
import Hero from "../components/Hero.astro";
_16
import SiteLayout from "../layouts/SiteLayout.astro";
_16
---
_16
_16
<SiteLayout>
_16
<div class="container col-xxl-8 px-4 py-5">
_16
<Hero
_16
title="Mi primera Astro web"
_16
imageUrl="https://placekitten.com/g/500/400"
_16
buttonText="Leer más"
_16
buttonLink="/about"
_16
>
_16
</Hero>
_16
</div>
_16
</SiteLayout>

💦 Comprueba que todo funciona y haz cambios en about.astro para que veas como poder sobreescribir el valor por defecto del <slot>

💪 ¡Los tienes controlados los componentes!

⚡️ Pon a prueba lo que has aprendido

1. ¿Qué es un 'slot' en Astro?
2. ¿Cómo se puede establecer un valor por defecto para un 'slot' en Astro?
3. ¿Cómo se pasa contenido a un 'slot' en un componente Astro?

Este contenido llega a ti gracias a la Comunidad de suscriptores de Web Reactiva