<aside> <img src="/icons/arrow-northeast_gray.svg" alt="/icons/arrow-northeast_gray.svg" width="40px" />

Índice

</aside>

<aside> <img src="/icons/notion_green.svg" alt="/icons/notion_green.svg" width="40px" />

Conteúdos

Introdução

Introdução ao Vue.js

Anatomia de um componente .vue

Interpolação e reatividade com ref e computed

Diretivas: v-bind, v-on, v-if, v-for e v-model

Componentes e props

Slots, emits e ciclo de vida

Introdução ao Nuxt.js

Criando o projeto Gumball Verse

Primeira requisição com useFetch

Rotas a partir de arquivos

Layout, base do projeto e nuxt.config.ts

Consumindo a API nas listagens

Páginas de detalhes com rotas dinâmicas

Tratando o erro 404 com createError

Títulos das páginas com useHead

Filtros, paginação e busca com debounce

Desafio: título e favicon dinâmicos

Conclusão e próximos passos

</aside>

Na página anterior vimos que as props levam dados do pai para o filho. Agora vamos completar a comunicação entre componentes: os slots levam conteúdo HTML para dentro do componente, e os emits permitem que o filho avise o pai quando algo acontece. Para fechar a Parte 1, vamos conhecer o ciclo de vida com onMounted.


Slots: passando HTML para dentro do componente

Prop serve para dado. Slot serve para conteúdo, ou seja, um pedaço de HTML. Crie o componente Card.vue:

<template>
    <article class="card">
        <slot />
    </article>
</template>

Para usar:

<Card>
    <h3>Gumball</h3>
    <p>Um gato azul de 12 anos.</p>
</Card>

Tudo o que fica entre <Card> e </Card> aparece no lugar do <slot />.

Slots nomeados

Quando o componente tem mais de um espaço para receber conteúdo, damos um nome a cada slot. Veja o componente FeatureCard.vue:

<template>
    <div class="feature">
        <span class="feature__icon"><slot name="icon" /></span>
        <h3>{{ title }}</h3>
    </div>
</template>

E para preencher o slot nomeado, usamos <template #nome>:

<FeatureCard title="245 personagens">
    <template #icon>
        <IconsUsers />
    </template>
</FeatureCard>

<aside> 💡 Guarde bem o <slot />: ele vai aparecer de novo quando criarmos o layout do projeto no Nuxt, onde cada página será exibida no lugar do slot.

</aside>


Emits: o filho avisando o pai

As props descem do pai para o filho; os eventos sobem do filho para o pai. Crie o componente filho SearchInput.vue:

<script setup>
const emit = defineEmits(['search']);
</script>

<template>
    <input @input="emit('search', $event.target.value)" placeholder="Buscar…" />
</template>

O defineEmits declara quais eventos o componente pode disparar. A cada letra digitada, o filho emite o evento search levando junto o valor do input.