Atualizado: 21/06/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Slots com escopo no Vue.js

Em determinados cenários, é necessário acessar dados internos de um componente filho no conteúdo que o componente pai envia para ele. Um caso comum ocorre quando se tenta acessar dados definidos no filho diretamente dentro do corpo do componente pai. Considere o seguinte código:

Componente pai:

<div id="app">
  <user>
    <h3>Dados do usuário</h3>
    <p>Nome: {{ user.name }}</p>
    <p>Idade: {{ user.age }}</p>
  </user>
</div>

Componente filho:

const app = Vue.createApp({});

app.component("user", {
  data() {
    return { user: { name: "Tom", age: 36 } };
  },
  template: `<div><slot></slot></div>`,
});

app.mount("#app");

Esse código não funciona porque o componente pai não tem acesso ao objeto user, que está definido apenas dentro do componente user. As expressões {{ user.name }} e {{ user.age }} estão fora do escopo e, por isso, não produzem nenhum valor visível.

Para resolver esse tipo de situação, pode-se recorrer aos slots com escopo (scoped slots). Esse recurso permite que o componente filho envie dados ao conteúdo que o pai define dentro do slot. Os dados disponibilizados pelo filho ficam acessíveis apenas dentro desse escopo.

No componente pai, o slot é declarado dentro de um <template> usando a diretiva v-slot. Essa diretiva recebe um identificador que representa os dados enviados pelo componente filho.

A seguir, um exemplo funcional usando scoped slots:

<!DOCTYPE html>
<html>
  <head>
    <title>Slots Vue 3</title>
    <meta charset="utf-8" />
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app">
      <user>
        <template v-slot:default="props">
          <h3>Dados do usuário</h3>
          <p>Nome: {{ props.userinfo.name }}</p>
          <p>Idade: {{ props.userinfo.age }}</p>
        </template>
      </user>
    </div>

    <script>
      const app = Vue.createApp({});

      app.component("user", {
        data() {
          return { user: { name: "Tom", age: 36 } };
        },
        template: `
        <div>
            <slot v-bind:userinfo="user"></slot>
        </div>
        `,
      });

      app.mount("#app");
    </script>
  </body>
</html>

Neste exemplo, o componente user disponibiliza o objeto user para o slot através de v-bind:userinfo="user". O componente pai define o conteúdo do slot padrão usando v-slot:default="props". Dessa forma, os dados são acessados por meio de props.userinfo.

Como o slot não possui um nome explícito, o Vue o trata como default, e a diretiva correspondente no pai é v-slot:default. O identificador props representa o objeto com os dados transmitidos e pode ter qualquer nome, desde que seja coerente com o uso interno.

Esse padrão também pode ser aplicado a listas, permitindo que o componente pai controle a estrutura visual de cada item:

<!DOCTYPE html>
<html>
  <head>
    <title>Slots Vue 3</title>
    <meta charset="utf-8" />
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="app">
      <userslist>
        <template v-slot:userdetails="props">
          <div>
            <p>Nome: {{ props.userinfo.name }}</p>
            <p>Idade: {{ props.userinfo.age }}</p>
          </div>
        </template>
      </userslist>
    </div>

    <script>
      const app = Vue.createApp({});

      app.component("userslist", {
        data() {
          return {
            users: [
              { name: "Tom", age: 36 },
              { name: "Sam", age: 39 },
              { name: "Bob", age: 25 },
            ],
          };
        },
        template: `
        <ul>
            <li v-for="user in users">
                <slot name="userdetails" v-bind:userinfo="user"></slot>
            </li>
        </ul>
        `,
      });

      app.mount("#app");
    </script>
  </body>
</html>

O componente userslist percorre o array users e, para cada item, dispara o slot nomeado userdetails, enviando o respectivo objeto pelo atributo v-bind:userinfo="user".

O componente pai define o conteúdo do slot userdetails usando a diretiva v-slot:userdetails="props", acessando os dados de cada usuário por meio de props.userinfo.

Esse padrão permite que o pai controle completamente a estrutura e a apresentação dos dados, enquanto o componente filho se responsabiliza apenas pela lógica de dados e repetição.

Renderizando lista com slots com escopo no Vue.js

Resumo

  • Scoped slots permitem que um componente filho envie dados ao conteúdo definido no slot pelo componente pai.
  • O slot é declarado no pai com <template v-slot:nome="variável">.
  • Os dados são enviados pelo filho com v-bind dentro do slot.
  • Quando o slot não possui nome, o Vue o trata como default, e o pai deve usar v-slot:default.
  • O pai pode acessar os dados enviados por meio do identificador declarado no v-slot.
  • Esse recurso oferece flexibilidade para controlar a estrutura visual no pai enquanto o filho gerencia os dados.

Documentação oficial:

Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com