Slots

Os Slots no Vue.js são uma funcionalidade que permite criar componentes reutilizáveis e ainda mais flexíveis. Eles funcionam como “espaços reservados” nos componentes onde você pode inserir conteúdo dinâmico.

🔍 Tipos de Slots

Existem três tipos principais de slots no Vue.js:

  1. Slot Padrão: O slot padrão é o mais simples e permite que você insira conteúdo em um componente.
  2. Slots Nomeados: Permitem que você defina múltiplos slots em um componente, cada um com um nome específico.
  3. Slots com Escopo: Permitem que um componente filho passe dados para o componente pai através do slot.

Slot Padrão (Default Slot)

O slot padrão é a forma mais simples de usar slots. Todo conteúdo passado para o componente será renderizado no local do .

<card-component>
  <h3 class="title is-4">Conteúdo no Slot Padrão</h3>
  <p>Este conteúdo está sendo passado através do slot padrão.</p>
</card-component>
// Definição do componente
const CardComponent = {
  template: `
    <div class="card mb-4">
      <div class="card-content">
        <slot></slot> <!-- Conteúdo será inserido aqui -->
      </div>
    </div>
  `
};

Slots Nomeados (Named Slots)

Os slots nomeados permitem definir múltiplos pontos de inserção de conteúdo em um componente, cada um com um nome específico.

<!-- Uso do componente -->
<card-component>
  <template #header>
    <h2 class="title is-3">Título no Header</h2>
  </template>

  <template #default>
    <p>Este é o conteúdo principal do card.</p>
    <button class="button is-primary" @click="showMessage">Clique aqui</button>
  </template>

  <template #footer>
    <p class="has-text-grey">Footer personalizado</p>
  </template>
</card-component>
// Definição do componente
const CardComponent = {
  template: `
    <div class="card mb-4">
      <header class="card-header" v-if="$slots.header">
        <div class="card-header-title">
          <slot name="header"></slot>
        </div>
      </header>
      <div class="card-content">
        <slot></slot> <!-- Slot padrão -->
      </div>
      <footer class="card-footer" v-if="$slots.footer">
        <div class="card-footer-item">
          <slot name="footer"></slot>
        </div>
      </footer>
    </div>
  `
};

Slots com Escopo (Scoped Slots)

Os slots com escopo permitem que o componente filho passe dados para o componente pai através do slot.

<user-card v-for="user in users" :key="user.id" :user="user">
  <template #default="{ user, isOnline }">
    <div class="media">
      <div class="media-left">
        <figure class="image is-64x64">
          <img class="is-rounded" :src="user.avatar" :alt="user.name">
        </figure>
      </div>
      <div class="media-content">
        <p class="title is-5"></p>
        <p class="subtitle is-6"></p>
        <span class="tag" :class="isOnline ? 'is-success' : 'is-danger'">
          
        </span>
      </div>
    </div>
  </template>
</user-card>

No exemplo acima, existe uma interpolação de dados user e isOnline.

export default {
  name: "UserComponent",
  props: {
    user: {
      type: String,
      required: true,
    },
  },
  template: `
    <div class="card mb-4">
        <div class="card-content">
            <slot :user="user" :isOnline="isUserOnline"></slot>
        </div>
    </div>
  `,
  computed: {
    isUserOnline() {
      return Math.random() > 0.5; // Simula status online/offline
    },
  },
};

Neste exemplo, o componente UserCard passa o valor de isOnline para o componente pai através do slot.

💡 Vantagens dos Slots

  • Flexibilidade: Permite personalizar componentes sem modificar sua estrutura
  • Reutilização: Um componente pode ser usado em diferentes contextos
  • Separação de Responsabilidades: O componente cuida da estrutura, o pai do conteúdo
  • Composição: Facilita a criação de layouts complexos

💡 Exemplo

Acesse o exemplo completo no repositório: https://github.com/rodrigoprestesmachado/cpw2/tree/dev/exemplos/vue-slots

Referências 📚

Rodrigo Prestes Machado
CC BY 4.0 DEED

Copyright © 2024 RPM Hub. Distributed by CC-BY-4.0 license.