Svelte 3: Composição de Componentes com Slots
Tags: ptbr, javascript, webdev, svelte
Published: 2019-07-07 10:05:04

## 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](https://medium.com/@oieduardorabelo/svelte-3-utilizando-props-8ee440507166):

```vue
<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:

```vue
<slot />
```

Ou com a tag de fechamento:

```vue
<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:

```vue
<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:

```vue
<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:

```vue
<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:

```vue
<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](https://svelte.dev/tutorial/slots) para mais exemplos de uso de slots no Svelte. Uma outra coisa interessante que você [pode aprender](https://svelte.dev/tutorial/slot-props) 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 ⭐️

- [Composing Your Svelte Components Using Slots](https://alligator.io/svelte/slots/), escrito originalmente por [@alligatorio](https://mobile.twitter.com/alligatorio)