Skip to content

Étape 17 — Transposition projet personnel

Objectif

Appliquer les concepts de la séquence 5 (favoris + persistance) à votre projet individuel.

Ce que vous avez appris

ConceptPokédexVotre projet
localStorageSauvegarder les IDs des Pokémon favorisSauvegarder les préférences/favoris de l'utilisateur
JSON.stringify() / JSON.parse()Convertir un tableau d'IDs en string et vice-versaStocker n'importe quelle donnée structurée
State favoritesTableau d'IDs dans le store PiniaVotre propre liste de favoris/sélections
Getter avec paramètreisFavorite(pokemon) retourne true/falseVérifier un état pour un élément donné
Getter calculégetFavorites transforme des IDs en objetsDériver des données complexes depuis le state
Action toggleAjoute ou retire un favori en un clicTout bouton on/off dans votre application
@click.stop.preventEmpêcher la navigation quand on clique sur le coeurTout bouton à l'intérieur d'un élément cliquable
v-if / v-elseAlerte "aucun favori" ou grille de cartesAffichage conditionnel selon l'état des données
Réutilisation de composantPokemonCard dans la page d'accueil ET la page favorisUn composant = un usage dans plusieurs contextes

Checklist projet perso

Avant de quitter, vérifiez que votre projet individuel a :

  • Un state favorites (ou équivalent) dans le store — tableau d'IDs
  • Une action toggleFavorite() qui ajoute ou retire un élément
  • Une action saveFavorites() qui persiste dans localStorage
  • Une action loadFavorites() appelée dans init() du store
  • Un getter isFavorite() utilisé pour changer l'apparence du bouton
  • Un getter getFavorites qui retourne les objets complets (pas juste les IDs)
  • Un bouton favori avec @click.stop.prevent (si le parent est cliquable)
  • Une page dédiée aux favoris avec un message "aucun favori" si la liste est vide
  • Les favoris persistent après rechargement de la page
  • Le composant carte est réutilisé sur la page d'accueil ET la page favoris
  • 0 erreurs dans la console
  • Commit poussé sur GitHub
  • Version en ligne vérifiée (Vercel ou GitHub Pages)

Prochaine séquence

La semaine prochaine, on ajoutera un formulaire d'ajout de Pokémon avec validation. Préparez-vous à comprendre :

  • v-model sur différents types de champs (texte, select, nombre)
  • Validation de formulaire avec les règles Vuetify
  • @submit.prevent pour empêcher le rechargement de la page
  • Requête POST vers l'API

Préparation oral — Concepts clés de la séquence 5

Questions que vous devez savoir expliquer :

  1. Pourquoi stocker des IDs plutôt que des objets complets dans les favoris ? Les IDs sont légers (une string) et stables. Les objets peuvent changer (niveau, stats...). On retrouve l'objet complet via pokemons.find(). Stocker des objets dans localStorage prendrait beaucoup plus de place et pourrait devenir obsolète.

  2. Qu'est-ce que localStorage et quelles sont ses limites ? C'est un espace de stockage dans le navigateur (~5 Mo) qui persiste même après fermeture. Il ne stocke que des strings — d'où JSON.stringify/parse. Il est synchrone (bloque le thread) et non sécurisé (tout script de la page peut y accéder). Il ne remplace pas une base de données.

  3. Pourquoi @click.stop.prevent et pas juste @click ? Parce que le bouton coeur est à l'intérieur d'un <v-card :to="..."> qui agit comme un lien. Sans .stop, le clic remonte au parent (<v-card>) qui déclenche la navigation. Sans .prevent, le comportement par défaut du <router-link> s'exécute quand même.

  4. Qu'est-ce qu'un getter avec paramètre dans Pinia ? C'est un getter qui retourne une fonction au lieu d'une valeur. On l'appelle avec un argument : isFavorite(pokemon). Ça permet de vérifier une condition pour un élément spécifique, pas juste pour l'état global.

  5. Pourquoi getFavorites utilise .filter(p => p !== undefined) ? Parce qu'un favori peut référencer un Pokémon qui a été supprimé de l'API. find() retournerait undefined pour cet ID. Le .filter() nettoie ces cas pour éviter des erreurs dans le template (Cannot read property 'name' of undefined).

  6. Quelle est la différence entre .stop et .prevent ? .stop appelle event.stopPropagation() — empêche l'événement de remonter aux éléments parents. .prevent appelle event.preventDefault() — empêche le comportement natif de l'élément (navigation d'un lien, soumission d'un formulaire, etc.). Ce sont deux mécanismes indépendants.

  7. Qu'est-ce que le pattern toggle ? C'est un pattern où une seule action fait deux choses opposées selon l'état actuel : si l'élément est dans la liste, on le retire ; sinon, on l'ajoute. Dans le Pokédex, toggleFavorite() vérifie si l'ID existe déjà dans favorites — si oui, splice pour retirer, sinon push pour ajouter. Un seul bouton, deux comportements.

Documentation pour les cours de développement web