Étape 4 — Page de détail avec route dynamique
Résultat final (toutes les séquences terminées)

Votre version n'aura pas encore les types colorés ni les statistiques — ils seront ajoutés dans les séquences suivantes.
Objectifs
- Créer une route dynamique (
/pokemon/:id) - Récupérer le paramètre d'URL avec
useRoute() - Rendre la carte Pokémon cliquable pour naviguer vers le détail
Contexte
On veut cliquer sur un Pokémon dans la grille pour voir sa fiche complète :
L'URL sera /pokemon/5566710e-... (l'ID du Pokémon).
Encart oral — Routes dynamiques
Une route dynamique contient un segment variable, noté [id] dans le nom de fichier.
useRoute() = lire les informations de la page actuelle (lecture seule) :
const route = useRoute()
// Sur l'URL /pokemon/abc123?lang=fr
route.params.id // → "abc123" (paramètre dynamique)
route.path // → "/pokemon/abc123" (chemin complet)
route.query.lang // → "fr" (paramètre de requête ?lang=fr)useRouter() = changer de page par code (navigation) :
const router = useRouter()
router.push('/') // → aller à la page d'accueil
router.push('/favoris') // → aller à la page favoris
router.back() // → retour à la page précédente (comme le bouton ← du navigateur)Analogie : useRoute() c'est le GPS (il vous dit où vous êtes). useRouter() c'est le volant (il vous permet d'aller ailleurs).
Tâches
1. Créer la page de détail
Créez d'abord le dossier src/pages/pokemon/, puis le fichier [id].vue à l'intérieur :
src/pages/
├── pokemon/ ← nouveau dossier
│ └── [id].vue ← nouveau fichier
├── index.vue
├── favoris.vue
├── a-propos.vue
└── [...path].vueCette page doit :
- Récupérer l'
iddepuisuseRoute().params.id - Appeler
fetch('http://localhost:3535/pokemons')pour charger tous les Pokémon - Trouver le Pokémon correspondant à l'
idavec.find() - Afficher : image (grande), nom, niveau, description
- Afficher un message d'erreur si le Pokémon n'est pas trouvé
- Ajouter un bouton "Retour" qui utilise
$router.back()
2. Rendre les cartes cliquables
Dans PokemonCard.vue, ajoutez la prop :to sur la <v-card> existante pour créer un lien vers la page de détail :
<v-card :to="`/pokemon/${pokemon.id}`" hover>:totransforme la carte en lien (navigation au clic)hoverest déjà présent depuis l'étape 2 (effet d'élévation au survol)
3. Tester
- Cliquez sur une carte → la page de détail s'affiche avec les bonnes données
- Le bouton "Retour" ramène à la page précédente
- Testez un ID invalide (ex:
/pokemon/xxx) → le message d'erreur s'affiche
Projet perso — À faire en parallèle
Dans votre projet individuel :
- Créez votre page de détail avec une route dynamique (
/item/[id].vueou similaire) - Rendez vos cartes cliquables vers la page de détail
- Affichez les données détaillées de l'élément sélectionné
- Ajoutez un bouton retour
Références utiles
Tests
- Cliquer sur une carte navigue vers
/pokemon/:id - La page de détail affiche l'image, le nom, le niveau et la description
- Le bouton "Retour" fonctionne
- Un ID invalide affiche le message d'erreur
- 0 erreurs dans la console
Solutions
src/pages/pokemon/[id].vue
<template>
<v-container>
<v-btn
variant="text"
prepend-icon="mdi-arrow-left"
class="mb-4"
@click="$router.back()"
>
Retour
</v-btn>
<v-alert
v-if="!pokemon"
type="error"
variant="tonal"
>
Pokémon non trouvé.
</v-alert>
<v-card
v-else
max-width="800"
class="mx-auto"
>
<v-img
:src="getImageUrl(pokemon.img)"
:alt="pokemon.name"
height="300"
cover
/>
<v-card-title class="text-h4">
{{ pokemon.name }}
</v-card-title>
<v-card-subtitle>
Niveau {{ pokemon.level }}
</v-card-subtitle>
<v-card-text>
<p v-if="pokemon.description" class="text-body-1 mb-4">
{{ pokemon.description }}
</p>
</v-card-text>
</v-card>
</v-container>
</template>
<script setup>
import { getImageUrl } from '@/utils/imageUrl'
const route = useRoute()
const pokemons = ref([])
const pokemon = computed(() => {
return pokemons.value.find(p => p.id === route.params.id)
})
onMounted(async () => {
const response = await fetch('http://localhost:3535/pokemons')
pokemons.value = await response.json()
})
</script>src/components/PokemonCard.vue (modification)
<v-card :to="`/pokemon/${pokemon.id}`" hover>Ajoutez :to et hover sur la balise <v-card> existante.
Commit
git add -A
git commit -m "feat: page détail Pokémon avec route dynamique"Problème à résoudre plus tard
Vous avez remarqué ? On appelle fetch() deux fois : une fois dans index.vue et une fois dans [id].vue. C'est du gaspillage. À la prochaine séquence (Pinia), on résoudra ce problème en centralisant les données dans un store.