Vue.js Slots: Conheça a nova sintaxe e descubra o que mudou
Você sabia que a partir da versão 2.6 houve uma mudança na sintaxe dos Slots? Este artigo mostra o que mudou da maneira mais simples possível.
Sobre os Slots e a versão 2.6
O Slot é um recurso extremamente útil para quem deseja desenvolver componentes com alto grau de reutilização. Frameworks como Vuetify e Quasar fazem uso deste recurso e entender o seu funcionamento é muito importante para extrair o máximo dessas ferramentas.
Embora a documentação dos Slots seja clara e concisa, vejo que a mudança de sintaxe lançada na versão 2.6 ainda deixa muita gente confusa. Durante o último semestre, alguns dos meus alunos relataram dificuldade para usar os Slots e por isso decidi escrever este artigo.
Dúvidas comuns sobre os Slots
A sintaxe antiga continua funcionando na versão 2.6, mas está depreciada e não terá mais suporte a partir da versão 3.0. A nova sintaxe funciona somente a partir da versão 2.6 e não funciona em versões anteriores.
Outra questão é que a sintaxe dos Slots mudou apenas na sua chamada, ou seja, a declaração dentro do componente continua igual.
Independente da alteração da versão 2.6, sempre existiu uma diferença entre declaração dos Slots dentro do componente para a declaração de chamada do componente. Mesmo antes desta versão, este item sempre gerou dúvidas, mas agora algumas pessoas se confundem mais ainda.
Named Slots
Quando você tem múltiplos Slots dentro de um componente, você deve usar os Slots nomeados. A sintaxe dentro do componente é a seguinte, vale ressaltar que essa sintaxe continua igual:
<template>
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
</div>
</template>
<script>
export default {
name: 'BaseLayout',
};
</script>
Antes da versão 2.6, para chamar este componente você precisava usar um atributo slot na chamada do seu componente:
<BaseLayout>
<template slot="header">
<h1>Meu título</h1>
</template>
<template slot="default">
<p>Meu texto</p>
</template>
</BaseLayout>
A partir da versão 2.6, você não usa mais o atributo slot, agora você deve utilizar o atributo v-slot. A sintaxe fica assim:
<BaseLayout>
<template v-slot:header>
<h1>Meu título</h1>
</template>
<template v-slot:default>
<p>Meu texto</p>
</template>
</BaseLayout>
Olhando superficialmente os códigos são parecidos, mas para quem usa Vue.js com frequência, essa alteração de sintaxe faz muito sentido.
Scoped Slots
Quando você chama um componente, dentro do Slot você só tem acesso as variáveis do componente pai. Porém, as vezes é necessário acessar alguma variável do componente filho e neste caso é necessário usar os Scoped Slots.
A sintaxe dos Scoped Slots é a seguinte:
<template>
<div class="container">
<header>
<slot name="header" :title="document.title"></slot>
</header>
<main>
<slot :text="document.text"></slot>
</main>
</div>
</template>
<script>
export default {
name: 'BaseLayout',
data: () => ({
document: {
title: 'Meu título',
text: 'Meu texto',
footer: 'Meu Rodapé',
},
}),
};
</script>
Perceba que a tag slot aceita propriedades que ficam relacionadas com variáveis do próprio componente. Quero destacar que essa sintaxe não mudou, continua igual na versão 2.6 e anteriores.
O que mudou foi na chamada do componente. Antes da versão 2.6 este componente deveria ser chamado da seguinte maneira:
<BaseLayout>
<template slot="header" slot-scope="{ title }">
<h1>{{ title.toUpperCase() }}</h1>
</template>
<template slot="default" slot-scope="{ text }">
<p>{{ text.toUpperCase() }}</p>
</template>
</BaseLayout>
Com a nova sintaxe a declaração fica assim:
<BaseLayout>
<template v-slot:header="{ title }">
<h1>{{ title.toUpperCase() }}</h1>
</template>
<template v-slot:default="{ text }">
<p>{{ text.toUpperCase() }}</p>
</template>
</BaseLayout>
Por fim, como mostrei nos exemplos, a mudança é bem sútil e não deve impactar significativamente no seu software.
Dúvidas ou sugestões é só entrar em contato. Abraço.