<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>
Agora vamos integrar a API nas rotas de detalhes de personagem e de lugar. A ideia é juntar duas coisas que já conhecemos: a rota dinâmica com useRoute e o useFetch. O id que vem da URL vira parte do endereço da API.
Abra o arquivo app/pages/characters/[id].vue e substitua o conteúdo por:
<script setup>
const route = useRoute();
const { id } = route.params;
const { data } = await useFetch(`https://gumball-api-server.vercel.app/characters/${id}`);
</script>
<template>
<section class="section section--details">
<div class="container">
<BackLink to="/characters">Todos os personagens</BackLink>
<CharacterDetails
:name="data.name"
:full-name="data.fullName"
:image="data.image"
:description="data.description"
:role="
data.role === 'main'
? 'Principal'
: data.role === 'minor'
? 'Secundário'
: 'Coadjuvante'
"
:status="
data.status === 'alive'
? 'Vivo'
: data.status === 'deceased'
? 'Morto'
: 'Morto-vivo'
"
:species="data.species"
:gender="data.gender"
:age="data.age ? `${data.age} anos` : 'Desconhecida'"
:occupation="data.occupation"
:animation-style="data.animationStyle"
:first-appearance-code="data.firstAppearance?.code"
:first-appearance-title="data.firstAppearance?.title"
:aliases="data.aliases"
:voice-actors="data.voiceActors"
:colors="data.colors"
:color="getCharacterColor(data.colors)"
/>
</div>
</section>
</template>
id da rota. Acessando /characters/7, a requisição vai para /characters/7 na API;CharacterDetails, que já cuida de toda a parte visual;main ou alive. Com operadores ternários encadeados, transformamos esses valores em textos em português, como Principal ou Vivo;data.age existir, exibimos, por exemplo, 12 anos. Caso contrário, exibimos Desconhecida;?. protege o acesso caso o personagem não tenha informação de primeira aparição.<aside>
💡 Os ternários encadeados funcionam como um if / else if / else em formato de expressão. Por exemplo: se o papel for main, é Principal; senão, se for minor, é Secundário; senão, é Coadjuvante.
</aside>
Agora abra o arquivo app/pages/locations/[id].vue e substitua o conteúdo por:
<script setup>
const route = useRoute();
const { id } = route.params;
const { data } = await useFetch(`https://gumball-api-server.vercel.app/locations/${id}`);
</script>
<template>
<section class="section section--details">
<div class="container">
<BackLink to="/locations">Todos os lugares</BackLink>
<LocationDetails
:name="data.name"
:image="data.image"
:description="data.description"
:type="data.type"
:parent-id="data.parent?.id"
:parent-name="data.parent?.name"
:first-appearance-code="data.firstAppearance?.code"
:first-appearance-title="data.firstAppearance?.title"
/>
</div>
</section>
</template>
A lógica é a mesma: pegamos o id da URL, buscamos o lugar na API e passamos os dados como props para o componente LocationDetails. Repare no uso do ?. em parent e firstAppearance, que podem não existir em todos os lugares.