Referência às expressões de modelo
A sintaxe de componente Astro é uma extensão do HTML. A sintaxe foi projetada para soar familiar a qualquer um com experiência em escrever HTML ou JSX, e adiciona suporte para incluir componentes e expressões JavaScript.
Expressões parecidas com JSX
Seção intitulada “Expressões parecidas com JSX”Você pode definir variáveis locais do JavaScript dentro do script frontmatter do componente entre as duas cercas de código (---) de um componente Astro. Você pode então injetar essas variáveis no modelo HTML do componente usando expressões parecidas com JSX!
Usando essa abordagem, você pode incluir valores dinâmicos que são calculados no frontmatter. Mas uma vez incluídos, esses valores não são reativos e nunca mudarão. Componentes Astro são modelos que só executam uma vez durante a etapa de renderização.
Veja abaixo mais exemplos de diferenças entre Astro e JSX.
Variáveis
Seção intitulada “Variáveis”Variáveis locais podem ser adicionadas ao HTML usando a sintaxe de chaves:
---const nome = "Astro";---<div> <h1>Olá {nome}!</h1> <!-- Produz <h1>Olá Astro!</h1> --></div>Atributos Dinâmicos
Seção intitulada “Atributos Dinâmicos”Variáveis locais podem ser usadas entre chaves para passar valores de atributos tanto para elementos HTML como para componentes:
---const nome = "Astro";---<h1 class={nome}>Expressões de atributo são suportadas</h1>
<MeuComponente atributoTemplateLiteralNome={`MeuNomeE${nome}`} />Atributos HTML vão ser convertidos para strings, portanto não é possível passar funções e objetos para elementos HTML. Por exemplo, você não pode atribuir um manipulador de eventos a um elemento HTML em um componente Astro:
---function tratarClique () { console.log("botão clicado!");}---<!-- ❌ Isso não funciona! ❌ --><button onClick={tratarClique}>Nada vai acontecer quando você me clicar!</button>Em vez disso, use um script no lado do cliente para adicionar o manipulador de evento, como você faria no JavaScript vanilla:
------<button id="botao">Clique em Mim</button><script> function tratarClique () { console.log("botão clicado!"); } document.getElementById("botao").addEventListener("click", tratarClique);</script>HTML Dinâmico
Seção intitulada “HTML Dinâmico”Variáveis locais podem ser usadas em funções parecidas com JSX para produzir elementos HTML gerados dinamicamente:
---const itens = ["Cachorro", "Gato", "Ornitorrinco"];---<ul> {itens.map((item) => ( <li>{item}</li> ))}</ul>Astro pode exibir HTML condicionalmente usando operadores lógicos JSX e expressões ternárias.
---const visivel = true;---{visivel && <p>Mostre-me!</p>}
{visivel ? <p>Mostre-me!</p> : <p>Ou mostre-me!</p>}Tags Dinâmicas
Seção intitulada “Tags Dinâmicas”Você também pode usar tags dinâmicas ao atribuir a uma variável o nome de uma tag HTML ou um componente importado:
---import MeuComponente from "./MeuComponente.astro";const Elemento = 'div'const Componente = MeuComponente;---<Elemento>Olá!</Elemento> <!-- renderiza como <div>Olá!</div> --><Componente /> <!-- renderiza como <MeuComponente /> -->Ao usar tags dinâmicas:
-
Os nomes de variáveis devem iniciar com maiúsculas. Por exemplo, use
Elemento, nãoelemento. Caso contrário, Astro tentará renderizar o nome da sua variável como uma tag HTML literal. -
Diretivas de hidratação não são suportadas. Ao usar as diretivas de hidratação
client:*(EN), o Astro precisa saber quais componentes devem fazer parte do bundle para produção, e o padrão de tags dinâmicas impede que isso funcione. -
A diretiva define:vars (EN) não é suportada. Se você não puder envolver os filhos com um elemento extra (como
<div>), então você pode adicionar manualmente umstyle={`--myVar:${value}`}ao seu Elemento.
Fragmentos
Seção intitulada “Fragmentos”O Astro suporta usar tanto <Fragment></Fragment> como a abreviação <></>.
Fragmentos podem ser úteis para evitar elementos de invólucro ao adicionar diretivas set:* (EN), como no exemplo seguinte:
---const stringHtml = '<p>Conteúdo HTML bruto</p>';---<Fragment set:html={stringHtml} />Diferenças entre Astro e JSX
Seção intitulada “Diferenças entre Astro e JSX”A sintaxe de componente Astro é um superconjunto do HTML. Ela foi projetada para parecer familiar a qualquer um com experiência com HTML ou JSX, mas existem algumas diferenças importantes entre arquivos .astro e JSX.
Atributos
Seção intitulada “Atributos”No Astro, você usa o formato padrão kebab-case para todos os atributos HTML em vez do camelCase usado no JSX. Isso funciona até para o class, que não é suportado pelo React.
<div className="caixa" dataValue="3" /><div class="caixa" data-value="3" />Múltiplos Elementos
Seção intitulada “Múltiplos Elementos”O modelo de um componente do Astro pode renderizar vários elementos sem a necessidade de envolver tudo em uma única <div> ou <>, diferente do JavaScript ou JSX.
---// Modelo com múltiplos elementos---<p>Não precisa envolver elementos dentro de um único elemento.</p><p>Astro suporta múltiplos elementos raiz em um modelo.</p>Comentários
Seção intitulada “Comentários”No Astro, você pode usar comentários HTML padrão ou comentários no estilo JavaScript.
------<!-- A sintaxe de comentários HTML é válida em arquivos .astro -->{/* A sintaxe de comentários JS também é válida */}Os comentários no estilo HTML serão incluídos no DOM do navegador, enquanto os JS serão ignorados. Para deixar mensagens TODO ou outras explicações somente em desenvolvimento, você pode querer usar comentários no estilo JavaScript em vez disso.
Utilitários de componente
Seção intitulada “Utilitários de componente”Astro.slots
Seção intitulada “Astro.slots”Astro.slots contém funções utilitárias para modificar os filhos passados via slot de um componente Astro.
Astro.slots.has()
Seção intitulada “Astro.slots.has()”Tipo: (slotName: string) => boolean
Você pode verificar se existe conteúdo para um nome de slot específico com Astro.slots.has(). Pode ser útil quando você quer envolver o conteúdo de um slot, mas só quer mostrar os elementos envolvidos quando o slot estiver em uso.
------<slot />
{Astro.slots.has('more') && ( <aside> <h2>More</h2> <slot name="more" /> </aside>)}Astro.slots.render()
Seção intitulada “Astro.slots.render()”Tipo: (slotName: string, args?: any[]) => Promise<string>
Você pode renderizar o conteúdo de um slot em uma string do HTML de forma assíncrona usando Astro.slots.render().
---const html = await Astro.slots.render('default');---<Fragment set:html={html} />Isso é para casos de uso avançados! Na maioria das vezes, é mais simples renderizar o conteúdo de um slot com o elemento
Astro.slots.render() aceita um segundo argumento opcional: um array de parâmetros que irão ser passados para qualquer função filho. Pode ser útil para componentes utilitários personalizados.
Por exemplo, o componente <Shout /> converte sua propriedade message para maiúsculas e passa para o slot padrão:
---const message = Astro.props.message.toUpperCase();let html = '';if (Astro.slots.has('default')) { html = await Astro.slots.render('default', [message]);}---<Fragment set:html={html} />Uma função de callback passada para um filho do componente <Shout /> vai receber o parâmetro message completamente maiúsculo:
---import Shout from "../components/Shout.astro";---<Shout message="slots!"> {(message) => <div>{message}</div>}</Shout>
<!-- É mostrado como <div>SLOTS!</div> -->Funções de callback podem ser passadas para slots nomeados dentro de uma tag HTML com o atributo slot. Esse elemento é usado apenas para transferir o callback para um slot nomeado e não será renderizado na página.
<Shout message="slots!"> <fragment slot="message"> {(message) => <div>{message}</div>} </fragment></Shout>Use um elemento HTML padrão para a tag ou qualquer tag minúscula (ex.: <fragment> em vez de <Fragment />) que não será interpretada como um componente. Não use o elemento HTML <slot> pois ele será interpretado como um slot do Astro.
Astro.self
Seção intitulada “Astro.self”Astro.self permite que componentes Astro sejam chamados recursivamente. Esse comportamento permite que você renderize um componente Astro a partir dele mesmo usando <Astro.self> no template do componente. Isso pode ajudar a iterar grandes conjuntos de dados e estruturas de dados aninhadas.
---const { items } = Astro.props;---<ul class="nested-list"> {items.map((item) => ( <li> <!-- Se houver alguma estrutura de dados aninhada, renderizamos `<Astro.self>` --> <!-- e as propriedades podem ser passadas através da chamada recursiva --> {Array.isArray(item) ? ( <Astro.self items={item} /> ) : ( item )} </li> ))}</ul>Esse componente poderia então ser usado dessa maneira:
---import NestedList from './NestedList.astro';---<NestedList items={['A', ['B', 'C'], 'D']} />E renderizaria o HTML dessa maneira:
<ul class="nested-list"> <li>A</li> <li> <ul class="nested-list"> <li>B</li> <li>C</li> </ul> </li> <li>D</li></ul>