Étape 14 – Créer une fiche de détail complète
🎯 Objectifs de l’étape
Dans cette étape, vous allez construire une fiche de détail enrichie pour chaque Pokémon à partir de son identifiant.
Vous apprendrez à :
- récupérer les données du Pokémon depuis le store,
- créer deux composants réutilisables (
PokemonTypesChips
etPokemonStats
), - afficher une fiche responsive et lisible avec Vuetify.
🧩 Chapitre 1 – Afficher les informations de base
1. Récupérer le Pokémon
Dans src/pages/pokemons/[id]/index.vue
:
vue
<script setup>
import { useRoute } from 'vue-router'
import { usePokemonStore } from '@/stores/pokemonStore'
const route = useRoute()
const pokemonStore = usePokemonStore()
const pokemon = pokemonStore.getPokemonById(route.params.id)
</script>
2. Afficher la fiche
Dans le bloc <template>
:
vue
<template>
<v-container v-if="pokemon">
<v-row class="align-start">
<v-col cols="12" md="4">
<v-img
:src="`/images/${pokemon.img}`"
:alt="pokemon.name"
height="300"
class="rounded"
contain
/>
</v-col>
<v-col cols="12" md="8">
<h1 class="text-h4 mb-2">{{ pokemon.name }}</h1>
<p class="text-subtitle-1 mb-2">Niveau : {{ pokemon.level }}</p>
<!-- Les types et stats seront ajoutés dans les chapitres suivants -->
<p class="mt-6 text-body-1">{{ pokemon.description }}</p>
<v-btn
to="/"
prepend-icon="mdi-arrow-left"
class="mt-8"
color="primary"
variant="tonal"
>
Retour
</v-btn>
</v-col>
</v-row>
</v-container>
<v-container v-else>
<v-alert type="error" class="text-center">
Pokémon introuvable.
</v-alert>
</v-container>
</template>
🧩 Chapitre 2 – Composant PokemonTypesChips
1. Créer le fichier src/components/PokemonTypesChips.vue
vue
<template>
<!-- Conteneur principal affichant les types d'un Pokémon -->
<div>
<!--
Puce pour chaque type de Pokémon
* v-for : Parcourt le tableau des types associés au Pokémon pour afficher chaque type sous forme de puce.
* :key="type.id" : Utilise `type.id` comme clé unique pour optimiser le rendu.
* class="ma-1" : Ajoute une marge uniforme autour de chaque puce (1 unité).
* :color : Définit dynamiquement la couleur de la puce à partir de la propriété `color` du type (valeur par défaut : 'grey').
type?.color : Utilise l'opérateur de coalescence nulle (?) pour fournir une couleur par défaut si `type.color` est indéfini.
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing
* text-color="white" : Rend le texte des puces blanc pour un meilleur contraste.
-->
<v-chip
v-for="type in pokemonTypes"
:key="type.id"
class="ma-1"
:color="type?.color || 'grey'"
text-color="white"
>
<!-- Affiche le nom du type ou "Inconnu" si le type est introuvable -->
{{ type?.name || 'Inconnu' }}
</v-chip>
</div>
</template>
<script setup>
/*
Importation des dépendances nécessaires :
- defineProps : Permet de définir les propriétés reçues par le composant.
- usePokemonStore : Fournit l'accès au magasin Pinia pour récupérer les données des types.
*/
import { computed, defineProps } from 'vue'
import { usePokemonStore } from '@/stores/pokemonStore'
// Définition des propriétés du composant
const props = defineProps({
pokemon: {
// Objet représentant un Pokémon. Contient un tableau `types` listant les identifiants des types associés.
type: Object,
required: true, // Cette propriété est obligatoire pour le bon fonctionnement du composant.
},
})
// Initialisation du magasin Pinia
const pokemonStore = usePokemonStore()
/*
Récupération des types associés au Pokémon
- Utilise computed pour créer une propriété réactive.
Ainsi, si les types du Pokémon changent, cette propriété sera mise à jour automatiquement.
- Parcourt les identifiants des types (`props.pokemon.types`) et récupère leurs données depuis le magasin.
- Fournit un tableau de types avec leurs propriétés (`name`, `color`, etc.).
*/
const pokemonTypes = computed(() =>
props.pokemon.types.map(typeId => pokemonStore.getTypeById(typeId))
)
</script>
2. Intégrer dans la fiche de détail
vue
<script setup>
import PokemonTypesChips from '@/components/PokemonTypesChips.vue'
</script>
Et dans le <template>
:
vue
<PokemonTypesChips :pokemon="pokemon" class="mt-4" />
🧩 Chapitre 3 – Composant PokemonStats
1. Créer le fichier src/components/PokemonStats.vue
vue
<template>
<!-- Conteneur principal des statistiques -->
<div class="pokemon-stats">
<!-- Boucle pour afficher chaque statistique avec son titre et sa barre de progression -->
<v-list-item v-for="(value, key) in stats" :key="key">
<!-- Affichage du nom de la statistique et de sa valeur -->
<v-list-item-title>{{ key.toUpperCase() }}: {{ value }}</v-list-item-title>
<!-- Barre de progression avec couleur directement liée à la statistique -->
<v-progress-linear
:color="statColors[key] || 'grey'"
height="25"
:model-value="value"
>
<strong>{{ value }}</strong>
</v-progress-linear>
</v-list-item>
</div>
</template>
<script setup>
/**
* Composant `PokemonStats`
* Gère l'affichage des statistiques des Pokémon avec des barres de progression colorées.
*/
// Propriétés (props) du composant
defineProps({
stats: {
type: Object, // Objet contenant les statistiques (par ex. : { hp: 45, attack: 60 }).
required: true, // Les statistiques sont nécessaires pour ce composant.
},
})
/**
* Couleurs associées aux statistiques des Pokémon.
* Ces couleurs sont utilisées directement dans le template.
*/
const statColors = {
hp: '#FF5959', // Rouge doux pour la santé.
attack: '#C03028', // Rouge sombre pour l'attaque.
defense: '#6890F0', // Bleu clair pour la défense.
speed: '#F08030', // Orange vif pour la vitesse.
}
</script>
<style scoped>
/* Styles locaux pour améliorer la présentation */
.pokemon-stats {
margin-top: 1rem; /* Ajout d'espace au-dessus du conteneur */
}
.v-list-item {
margin-bottom: 1rem; /* Ajout d'espace entre les statistiques */
}
</style>
2. Intégrer dans la fiche de détail
vue
<script setup>
import PokemonStats from '@/components/PokemonStats.vue'
</script>
Et dans le <template>
:
vue
<PokemonStats :stats="pokemon.stats" class="mt-6" />
✅ Résultat final
Vous avez maintenant une fiche de détail complète avec :
- image, nom, niveau, description,
- les types sous forme de
chips
, - les statistiques avec barres de progression.
✅ Résultat final
Vous avez maintenant une fiche de détail complète avec :
- l’image du Pokémon,
- son nom, son niveau et sa description,
- ses types affichés sous forme de
chips
colorées, - ses statistiques illustrées avec des barres de progression.
Cette fiche est responsive et lisible sur mobile comme sur ordinateur.
📦 Composants Vuetify utilisés
Composant | Rôle |
---|---|
v-img | Affiche l’image du Pokémon |
v-container | Structure générale de la page |
v-row , v-col | Grille responsive pour organiser les colonnes |
v-alert | Affiche un message si le Pokémon est introuvable |
v-btn | Bouton pour revenir à l’accueil |
v-chip | Affiche les types du Pokémon |
v-progress-linear | Représente visuellement les statistiques numériques |
🧪 Tests à effectuer
- Naviguez vers différentes URLs de type
/pokemons/:id
dans le navigateur. - Vérifiez que l’image, le nom, le niveau, la description, les types et les stats s’affichent correctement.
- Essayez une URL invalide (ex.
/pokemons/xyz
) et assurez-vous que le message d’erreur s’affiche. - Cliquez sur le bouton Retour pour revenir à la page d’accueil sans erreur.