DEV Community

Eduardo Rabelo
Eduardo Rabelo

Posted on

Svelte 3: Composição de Componentes com Slots

Aplicativos web aprimorados ciberneticamente

No Svelte, os componentes podem ser compostos juntos usando slots. Composição significa permitir que seus componentes contenham outros componentes ou elementos HTML. Slots são possíveis no Svelte usando o componente <slot> dentro de componentes que podem aceitar componentes ou marcações.

É algo que já estamos acostumados a fazer naturalmente com elementos HTML. Vamos demonstrar como usar o componente <slot> construindo um componente Card.

Este componente Card é semelhante ao que eu usei para demonstrar a utilização de props no Svelte:

<script>
  export let title;
  export let imageUrl;
</script>

<style>
  /* Algo para deixar isso bonito */
</style>

<section>
  <h1>
    <img src={imageUrl} alt="Avatar for {title}" />
     {title}
  </h1>

  <div>
    <slot />
  </div>
</section>

Como você pode ver, simplesmente colocamos o <slot> onde quisermos permitir que os usuários do componente possam adicionar componentes customizados ou marcação.

Podemos usá-lo de uma maneira que fecha automaticamente:

<slot />

Ou com a tag de fechamento:

<slot></slot>

Espaço reservado e conteúdo de fallback

Você pode colocar o conteúdo de fallback dentro do <slot> e esse conteúdo será usado se o componente for usado sem elementos dentro:

<script>
  export let title;
  export let imageUrl;
</script>

<style>
  /* Algo para deixar isso bonito */
</style>

<section>
  <h1>
    <img src={imageUrl} alt="Avatar for {title}" />
     {title}
  </h1>

  <div>
    <slot>
      <p>😢 Sem detalhes!</p>
    </slot>
  </div>
</section>

Podemos usar o Card da seguinte maneira:

<script>
  import Card from "./Card.svelte";

  const items = [
    {
      title: "Pirate",
      description: "Argg!!",
      imageUrl: "https://alligator.io/images/pirate.svg"
    },
    {
      title: "Chef",
      description: "À la soupe!",
      imageUrl: "https://alligator.io/images/chef.svg"
    }
  ];
</script>

{#each items as item}
  <Card title={item.title} imageUrl={item.imageUrl}>
    <hr />
    <p>{item.description}</p>
  </Card>
{/each}

Com isso, uma linha horizontal e um parágrafo com a descrição do item aparecerão dentro de nosso componente Card no lugar do <slot>.

Slots nomeados

Você não está limitado a apenas um slot por componente. Você pode nomear seus slots usando o atributo name no componente <slot> e, em seguida, pode ter quantos slots desejar dentro de um componente.

Como você pode ver no exemplo a seguir, você também pode combinar slots nomeados com um slot padrão/sem nome:

<style>
  /* Faça-o bonito! */
</style>

<section>
  <slot name="title" />

  <slot name="description">
    <p>😮 Sem descrição!</p>
  </slot>

  <footer>
    <slot />
  </footer>
</section>

E fazemos uso dos slots nomeados adicionando um atributo name ao elemento pai para cada local do slot:

<script>
  import Card from "./Card.svelte";

  const items = [
    {
      title: "Pirate",
      description: "Argg!!",
      imageUrl: "https://alligator.io/images/pirate.svg"
    },
    {
      title: "Chef",
      description: "À la soupe!",
      imageUrl: "https://alligator.io/images/chef.svg"
    }
  ];
</script>

{#each items as item}
  <Card>
    <h1 slot="title">
      <img src={item.imageUrl} alt="Avatar for {item.title}" />
       {item.title}
    </h1>

    <p slot="description">{item.description}</p>

    <p>Something else!</p>
  </Card>
{/each}

Lembre-se, só pode haver um slot padrão!

Finalizando

🦄 Agora vá e componha o conteúdo do seu coração! Confira o tutorial oficial para mais exemplos de uso de slots no Svelte. Uma outra coisa interessante que você pode aprender com o tutorial é que os slots podem usar props, chamados de slot props, para passar props de volta ao componente que estão o usando.

Créditos ⭐️

Top comments (0)