Introdução aos Slots no Vue.js
Os slots fornecem um mecanismo para estruturar um componente de maneira fixa, permitindo que o conteúdo de diferentes partes seja definido pelo componente pai. No Vue.js, os slots são implementados através do elemento <slot>
, que é substituído pelo conteúdo enviado pelo componente pai dentro do componente filho.
Considere o seguinte exemplo:
<!DOCTYPE html>
<html>
<head>
<title>Slots no Vue 3</title>
<meta charset="utf-8" />
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<child-component><h2>Vue App</h2></child-component>
</div>
<script>
const app = Vue.createApp({});
app.component("child-component", {
template: `<div> <h3>Child Component</h3> </div>`,
});
app.mount("#app");
</script>
</body>
</html>
No código acima, dentro do elemento <child-component>
, que representa o componente filho, foi definido um conteúdo, um elemento <h2>Vue App</h2>
. Entretanto, ao renderizar, o Vue substitui completamente esse elemento e todo o seu conteúdo pelo template do componente, definido na propriedade template
. Isso significa que o conteúdo enviado pelo componente pai não influencia o resultado final.
Agora, aplicando slots, um elemento <slot></slot>
é inserido no template do componente filho:
<div id="app">
<child-component><h2>Vue App</h2></child-component>
</div>
<script>
const app = Vue.createApp({});
app.component("child-component", {
template: `<div>
<slot></slot>
<h3>Child Component</h3>
</div>`,
});
app.mount("#app");
</script>
Ao renderizar, o conteúdo dentro do <child-component>
, enviado pelo componente pai, será inserido no local onde o <slot>
está definido no template do componente filho. Assim, o título <h2>Vue App</h2>
será corretamente exibido.
O conteúdo enviado para os slots pode ser mais complexo do que apenas um único elemento. Um grupo de elementos pode ser passado para o componente filho. Além disso, o elemento <slot>
pode ser usado múltiplas vezes no template, permitindo que o conteúdo enviado pelo componente pai seja inserido em diferentes posições:
<div id="app">
<child-component>
<h2>Slot</h2>
<p>Isso é um slot</p>
</child-component>
</div>
<script>
const app = Vue.createApp({});
app.component("child-component", {
template: `<div>
<slot></slot>
<h3>Child Component</h3>
<slot></slot>
</div>`,
});
app.mount("#app");
</script>
Nesse caso, o conteúdo enviado pelo componente pai será inserido em ambos os slots dentro do template do componente filho.
Conteúdo Padrão dos Slots
Em alguns cenários, o componente pai pode não fornecer nenhum conteúdo para o slot do componente filho. Quando isso ocorre, é possível definir um conteúdo padrão para o slot, que será exibido caso nenhum conteúdo seja passado.
No exemplo abaixo, o componente ads
representa um bloco de anúncios. O anúncio é inserido através do slot. Se nenhum conteúdo for enviado pelo componente pai, o slot usará um valor padrão:
<!DOCTYPE html>
<html>
<head>
<title>Slots no Vue 3</title>
<meta charset="utf-8" />
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<ads></ads>
<ads>
<div>
<p>Inscrições abertas para cursos gratuitos da Udacity.</p>
<p>As candidaturas podem ser enviadas até 16 de outubro.</p>
</div>
</ads>
</div>
<script>
const app = Vue.createApp({});
app.component("ads", {
template: `<div>
<h3>Publicidade</h3>
<slot>Aqui poderia estar o seu anúncio</slot>
</div>`,
});
app.mount("#app");
</script>
</body>
</html>
O primeiro <ads></ads>
não recebe nenhum conteúdo, então o slot exibe a mensagem padrão "Aqui poderia estar o seu anúncio"
. Já no segundo <ads>
, um bloco de texto é enviado e substitui o conteúdo padrão do slot.
Resumo
- Slots permitem que um componente receba conteúdo do componente pai.
- O
<slot>
no template do componente filho é substituído pelo conteúdo enviado pelo pai. - Vários
<slot>
podem ser usados no mesmo componente para inserir conteúdo em diferentes posições. - Se o pai não fornecer conteúdo, o slot pode exibir um valor padrão definido no template do filho.
Documentação oficial: