<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
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
Criando o projeto Gumball Verse
Primeira requisição com useFetch
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
</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.
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 />.
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>
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.