Skip to content

Component

Els components estan dissenyats per ser reutilitzables i composables. Pots utilitzar components dins d’altres components per construir interfícies d’usuari cada cop més avançades. Per exemple, un component Button podria utilitzar-se per crear un component ButtonGroup:

src/components/ButtonGroup.astro
---
import Button from './Button.astro';
---
<div>
<Button title="Button 1" />
<Button title="Button 2" />
<Button title="Button 3" />
</div>

Són components de plantilla només HTML sense temps d’execució al costat del client i utilitzen l’extensió de fitxer .astro.

El més important que cal saber sobre els components Astro és que no es renderitzen al client. Es renderitzen a HTML sigui durant la compilació o sota demanda. Pots incloure codi JavaScript dins del “frontmatter” del teu component, i tot serà eliminat de la pàgina final enviada als navegadors dels teus usuaris. El resultat és un lloc més ràpid, sense cap empremta de JavaScript afegida per defecte.

Quan el teu component Astro necessita interactivitat al costat del client, pots afegir etiquetes <script> HTML estàndard o components de Framework UI com a “illes client”.

Per als components que necessiten renderitzar contingut personalitzat o dinàmic, pots ajornar la seva renderització al servidor afegint una directiva de servidor. Aquestes “illes de servidor” renderitzaran el seu contingut quan estigui disponible, sense retardar la càrrega completa de la pàgina.

Un component Astro està format per dues parts principals: l’Script del Component i la Plantilla del Component. Cada part realitza una funció diferent, però juntes proporcionen un marc de treball que és fàcil d’utilitzar i prou expressiu per gestionar qualsevol cosa que vulguis construir.

---
// Component Script (JavaScript)
---
<!-- Component Template (HTML + JS Expressions) -->

Astro utilitza una tanca de codi (---) per identificar l’script del component en el teu component Astro. Si has escrit Markdown abans, potser ja estàs familiaritzat amb un concepte similar anomenat frontmatter. La idea d’Astro sobre l’script del component està directament inspirada en aquest concepte.

Pots utilitzar l’script del component per escriure qualsevol codi JavaScript que necessitis per renderitzar la teva plantilla. Això pot incloure:

  • importar altres components Astro
  • importar components d’altres frameworks, com React
  • importar dades, com un fitxer JSON
  • obtenir contingut d’una API o base de dades
  • crear variables que faràs servir en la teva plantilla
src/components/MyComponent.astro
---
import SomeAstroComponent from '../components/SomeAstroComponent.astro';
import SomeReactComponent from '../components/SomeReactComponent.jsx';
import someData from '../data/pokemon.json';
// Access passed-in component props, like `<X title="Hello, World" />`
const { title } = Astro.props;
// Fetch external data, even from a private API or database
const data = await fetch('SOME_SECRET_API_URL/users').then(r => r.json());
---
<!-- Your template here! -->

La tanca de codi està dissenyada per garantir que el JavaScript que hi escrius quedi “tancat”. No s’escaparà a la teva aplicació frontend ni arribarà a mans dels teus usuaris. Pots escriure amb seguretat codi que sigui costós o sensible (com una crida a la teva base de dades privada) sense preocupar-te que acabi al navegador dels teus usuaris.

La plantilla del component es troba sota la tanca de codi i determina la sortida HTML del teu component. Si escrius HTML pla aquí, el teu component renderitzarà aquest HTML en qualsevol pàgina Astro on sigui importat i utilitzat. No obstant això, la sintaxi de plantilla de components d’Astro també admet expressions JavaScript, etiquetes <style> i <script> d’Astro, components importats, i directives especials d’Astro. Les dades i valors definits en l’script del component es poden utilitzar en la plantilla del component per produir HTML creat dinàmicament.

src/components/MyFavoritePokemon.astro
---
// Your component script here!
import Banner from '../components/Banner.astro';
import Avatar from '../components/Avatar.astro';
import ReactPokemonComponent from '../components/ReactPokemonComponent.jsx';
const myFavoritePokemon = [/* ... */];
const { title } = Astro.props;
---
<!-- HTML comments supported! -->
{/* JS comment syntax is also valid! */}
<Banner />
<h1>Hello, world!</h1>
<!-- Use props and other variables from the component script: -->
<p>{title}</p>
<!-- Delay component rendering and provide fallback loading content: -->
<Avatar server:defer>
<svg slot="fallback" class="generic-avatar" transition:name="avatar">...</svg>
</Avatar>
<!-- Include other UI framework components with a `client:` directive to hydrate: -->
<ReactPokemonComponent client:visible />
<!-- Mix HTML with JavaScript expressions, similar to JSX: -->
<ul>
{myFavoritePokemon.map((data) => <li>{data.name}</li>)}
</ul>
<!-- Use a template directive to build class names from multiple strings or even objects! -->
<p class:list={["add", "dynamic", { classNames: true }]} />

Un component Astro pot definir i acceptar props. Aquestes props després esdevenen disponibles per a la plantilla del component per renderitzar HTML. Les props són accessibles a través del global Astro.props en el teu script frontmatter.

Aquí tens un exemple d’un component que rep una prop greeting i una prop name. Fixa’t que les props que es rebran es desestructuren de l’objecte global Astro.props.

src/components/GreetingHeadline.astro
---
// Usage: <GreetingHeadline greeting="Howdy" name="Partner" />
const { greeting, name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>

Aquest component, quan s’importa i es renderitza en altres components, layouts o pàgines d’Astro, pot passar aquestes props com a atributs:

src/components/GreetingCard.astro
---
import GreetingHeadline from './GreetingHeadline.astro';
const name = 'Astro';
---
<h1>Greeting Card</h1>
<GreetingHeadline greeting="Hi" name={name} />
<p>I hope you have a wonderful day!</p>

També pots definir les teves props amb TypeScript utilitzant una interfície de tipus Props. Astro detectarà automàticament la interfície Props en el teu frontmatter i proporcionarà avisos/errors de tipus. Aquestes props també poden tenir valors per defecte quan es desestructuren d’Astro.props.

src/components/GreetingHeadline.astro
---
interface Props {
name: string;
greeting?: string;
}
const { greeting = "Hello", name } = Astro.props;
---
<h2>{greeting}, {name}!</h2>

Les props dels components poden tenir valors per defecte que s’utilitzaran quan no se’n proporcionin.

src/components/GreetingHeadline.astro
---
const { greeting = "Hello", name = "Astronaut" } = Astro.props;
---
<h2>{greeting}, {name}!</h2>

L’element <slot /> és un marcador de posició per a contingut HTML extern, que permet injectar (o “ranura”) elements fills des d’altres fitxers a la teva plantilla de component.

Per defecte, tots els elements fills passats a un component es renderitzaran en el seu `.

src/components/Wrapper.astro
---
import Header from './Header.astro';
import Logo from './Logo.astro';
import Footer from './Footer.astro';
const { title } = Astro.props;
---
<div id="content-wrapper">
<Header />
<Logo />
<h1>{title}</h1>
<slot /> <!-- children will go here -->
<Footer />
</div>
src/pages/fred.astro
---
import Wrapper from '../components/Wrapper.astro';
---
<Wrapper title="Fred's Page">
<h2>All about Fred</h2>
<p>Here is some stuff about Fred.</p>
</Wrapper>

Aquest patró és la base d’un component de disposició (layout) d’Astro: una pàgina sencera de contingut HTML pot ser “embolicada” amb les etiquetes <SomeLayoutComponent></SomeLayoutComponent> i enviada al component per renderitzar-se dins dels elements comuns de la pàgina definits allà.

Continua: Components

Els layouts són components d’Astro utilitzats per proporcionar una estructura d’UI reutilitzable, com ara una plantilla de pàgina.

Tradicionalment utilitzem el terme “layout” per referir-nos a components d’Astro que proporcionen elements comuns de la interfície d’usuari compartits entre pàgines, com ara capçaleres, barres de navegació i peus de pàgina.

Un component de layout típic d’Astro proporciona a una Pàgina:

  • una estructura bàsica de pàgina (<html>, <head> i <body> tags)
  • un <slot /> per especificar on ha d’injectar-se el contingut individual de la pàgina.

Però no hi ha res especial en un component de layout! Poden acceptar props i importar i utilitzar altres components com qualsevol altre component d’Astro. Poden incloure components de frameworks d’interfície d’usuari i scripts del costat del client. Ni tan sols han de proporcionar una estructura completa de pàgina, i poden utilitzar-se com a plantilles parcials de la interfície d’usuari.

Tanmateix, si un component de layout conté una estructura de pàgina, el seu element <html> ha de ser el pare de tots els altres elements dins del component.

Els components de layout habitualment es col·loquen al directori src/layouts del projecte per mantenir l’organització, però no és un requisit; pots decidir col·locar-los en qualsevol lloc del teus projecte. Fins i tot pots col·locar components de layout al costat de les teves pàgines prefixant els noms dels layouts amb _.

src/pages/index.astro
---
import SiteLayout from '../layouts/SiteLayout.astro';
---
<SiteLayout title="Home Page">
<p>My page content, wrapped in a layout!</p>
</SiteLayout>
src/layouts/SiteLayout.astro
---
import Head from '../components/Head.astro';
import Footer from '../components/Footer.astro';
const {title} = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<Head title={title}/>
</head>
<body>
<nav>
<a href="#">Home</a>
<a href="#">Posts</a>
<a href="#">Contact</a>
</nav>
<h1 class="text-xl">{title}</h1>
<article>
<slot/> <!-- your content is injected here -->
</article>
<Footer/>
</body>
</html>

Qualsevol “layaout” d’Astro es pot modificar per introduir la seguretat de tipus i l’autocompletat proporcionant els tipus per a les vostres propietats (props):

src/components/MyLayout.astro
---
interface Props {
title: string;
description: string;
publishDate: string;
viewCount: number;
}
const { title, description, publishDate, viewCount } = Astro.props;
---
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="description" content={description}>
<title>{title}</title>
</head>
<body>
<header>
<p>Published on {publishDate}</p>
<p>Viewed by {viewCount} folks</p>
</header>
<main>
<slot />
</main>
</body>
</html>

Els components de disseny no necessiten contenir tot el codi HTML d’una pàgina. Podeu dividir els vostres dissenys en components més petits i combinar components de disseny per crear plantilles de pàgina encara més flexibles. Aquest patró és útil quan voleu compartir codi entre diversos dissenys.

Per exemple, un component de disseny BlogPostLayout.astro podria donar estil al títol d’una entrada, la data i l’autor. Llavors, un BaseLayout.astro que s’aplica a tot el lloc podria gestionar la resta de la plantilla de la pàgina, com la navegació, els peus de pàgina, les etiquetes meta per a SEO, els estils globals i les fonts. També podeu passar propietats (props) rebudes des de la vostra entrada a un altre disseny, com qualsevol altre component niat.

TODO Millorar exemple

src/layouts/BlogPostLayout.astro
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout url={frontmatter.url}>
<h1>{frontmatter.title}</h1>
<h2>Post author: {frontmatter.author}</h2>
<slot />
</BaseLayout>

El contingut d'aquest lloc web té llicència CC BY-NC-ND 4.0.

©2022-2025 xtec.dev