Pular para o conteúdo

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.

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!

Variáveis locais podem ser adicionadas ao HTML usando a sintaxe de chaves:

src/components/Variaveis.astro
---
const nome = "Astro";
---
<div>
<h1>Olá {nome}!</h1> <!-- Produz <h1>Olá Astro!</h1> -->
</div>

Variáveis locais podem ser usadas entre chaves para passar valores de atributos tanto para elementos HTML como para componentes:

src/components/AtributosDinamicos.astro
---
const nome = "Astro";
---
<h1 class={nome}>Expressões de atributo são suportadas</h1>
<MeuComponente atributoTemplateLiteralNome={`MeuNomeE${nome}`} />

Variáveis locais podem ser usadas em funções parecidas com JSX para produzir elementos HTML gerados dinamicamente:

src/components/HtmlDinamico.astro
---
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.

src/components/HtmlCondicional.astro
---
const visivel = true;
---
{visivel && <p>Mostre-me!</p>}
{visivel ? <p>Mostre-me!</p> : <p>Ou mostre-me!</p>}

Você também pode usar tags dinâmicas ao atribuir a uma variável o nome de uma tag HTML ou um componente importado:

src/components/TagsDinamicas.astro
---
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ão elemento. 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 um style={`--myVar:${value}`} ao seu Elemento.

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:

src/components/SetHtml.astro
---
const stringHtml = '<p>Conteúdo HTML bruto</p>';
---
<Fragment set:html={stringHtml} />

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.

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.

exemplo.astro
<div className="caixa" dataValue="3" />
<div class="caixa" data-value="3" />

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.

src/components/ElementosRaiz.astro
---
// 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>

No Astro, você pode usar comentários HTML padrão ou comentários no estilo JavaScript.

exemplo.astro
---
---
<!-- A sintaxe de comentários HTML é válida em arquivos .astro -->
{/* A sintaxe de comentários JS também é válida */}

Astro.slots contém funções utilitárias para modificar os filhos passados via slot de um componente Astro.

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.

src/pages/index.astro
---
---
<slot />
{Astro.slots.has('more') && (
<aside>
<h2>More</h2>
<slot name="more" />
</aside>
)}

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} />

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:

src/components/Shout.astro
---
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:

src/pages/index.astro
---
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 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.

NestedList.astro
---
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>
Contribua Comunidade Sponsor