Skip to content

Étape 22 — Navigation responsive ​

Objectifs ​

  • Ajouter un tiroir de navigation (v-navigation-drawer) pour les écrans mobiles
  • Utiliser le bouton hamburger (v-app-bar-nav-icon) pour ouvrir/fermer le tiroir
  • Cacher les boutons desktop sur mobile avec les classes utilitaires Vuetify
  • Afficher les liens dans une v-list à l'intérieur du tiroir

Prérequis — Point de départ ​

Cette étape nécessite d'avoir terminé les étapes 1 à 21 (séquences 1-7). Si votre code n'est pas à jour, vous pouvez repartir de la branche etape-22-start :

bash
# Ajouter le dépôt du prof (une seule fois)
git remote add prof https://github.com/fallinov/esig-141-pokedex-vuetify.git
# Récupérer les branches et basculer
git fetch prof
git checkout -b etape-22-start prof/etape-22-start
npm install

Voir la branche sur GitHub

Résultat attendu ​

Navigation responsive avec tiroir mobile

Contexte ​

Actuellement, la barre de navigation affiche tous les boutons en ligne. Sur un petit écran (smartphone), ces boutons prennent trop de place ou disparaissent. La solution standard : un menu hamburger qui ouvre un tiroir latéral sur mobile, et des boutons visibles uniquement sur desktop.

Encart oral — Classes d'affichage responsive Vuetify

Vuetify fournit des classes utilitaires pour afficher/cacher des éléments selon la taille de l'écran :

ClasseEffet
d-noneCaché par défaut (toutes tailles)
d-md-flexAffiché en flex à partir de md (960px)
d-md-noneCaché à partir de md
d-none d-md-flexCaché sur mobile, visible sur desktop
d-md-noneVisible sur mobile, caché sur desktop

Combinées, ces classes permettent d'avoir deux navigations : une pour mobile (tiroir) et une pour desktop (boutons).

Tâches ​

1. Ajouter le bouton hamburger ​

Dans AppHeader.vue, ajoutez un v-app-bar-nav-icon au début du contenu de la v-app-bar. Ce bouton ne doit être visible que sur les petits écrans :

ComposantRôleDocumentation
<v-app-bar-nav-icon>Bouton hamburger standard pour ouvrir un tiroirApp bars
vue
<v-app-bar-nav-icon
  class="d-md-none"
  @click="drawer = !drawer"
/>
  • class="d-md-none" : visible uniquement sur mobile (caché à partir de md)
  • @click="drawer = !drawer" : bascule l'état du tiroir

Dans le <script setup>, créez la variable réactive :

js
const drawer = ref(false)

2. Cacher les boutons desktop sur mobile ​

Ajoutez la classe d-none d-md-flex sur chaque <v-btn> de navigation dans la barre. Ainsi, ils sont cachés sur mobile et visibles à partir de md :

vue
<v-btn
  v-for="link in menuItems"
  :key="link.title"
  :icon="link.icon"
  :to="link.path"
  class="d-none d-md-flex"
/>

Faites de même pour les autres boutons de la barre (favoris, login, etc.).

3. Définir les éléments de menu ​

Créez un tableau avec les liens de navigation :

js
const menuItems = [
  { title: 'Accueil', path: '/', icon: 'mdi-pokeball' },
  { title: 'Favoris', path: '/favoris', icon: 'mdi-heart' },
  { title: 'À propos', path: '/a-propos', icon: 'mdi-information' },
]

4. Ajouter le tiroir de navigation ​

Après la </v-app-bar>, ajoutez un v-navigation-drawer :

ComposantRôleDocumentation
<v-navigation-drawer>Panneau latéral coulissantNavigation drawers
<v-list>Liste d'éléments cliquablesLists
vue
<v-navigation-drawer
  v-model="drawer"
  temporary
>
  <v-list nav>
    <v-list-item
      v-for="link in menuItems"
      :key="link.title"
      :prepend-icon="link.icon"
      :title="link.title"
      :to="link.path"
      @click="drawer = false"
    />
  </v-list>
</v-navigation-drawer>

Points importants :

  • v-model="drawer" : contrôle l'ouverture/fermeture du tiroir
  • temporary : le tiroir se ferme quand on clique en dehors
  • nav sur <v-list> : ajoute du padding adapté à la navigation
  • @click="drawer = false" : ferme le tiroir quand on clique sur un lien
  • :to="link.path" : navigation avec Vue Router (pas de rechargement de page)

5. Tester le responsive ​

  1. Ouvrez les DevTools de votre navigateur (F12)
  2. Activez le mode responsive (icône smartphone/tablette)
  3. Réduisez la largeur sous 960px → le hamburger apparaît, les boutons disparaissent
  4. Cliquez sur le hamburger → le tiroir s'ouvre avec les liens
  5. Cliquez sur un lien → le tiroir se ferme et la navigation fonctionne
  6. Élargissez au-dessus de 960px → les boutons réapparaissent, le hamburger disparaît

Tests ​

  • Sur mobile (< 960px) : le bouton hamburger est visible
  • Sur mobile : les boutons de navigation desktop sont cachés
  • Cliquer sur le hamburger ouvre le tiroir latéral
  • Le tiroir contient tous les liens de navigation
  • Cliquer sur un lien dans le tiroir navigue et ferme le tiroir
  • Cliquer en dehors du tiroir le ferme
  • Sur desktop (>= 960px) : les boutons sont visibles, le hamburger est caché
  • 0 erreurs dans la console

Solution ​

src/components/AppHeader.vue
vue
<template>
  <!--
  Barre d'application plate
    * flat supprime l'ombre sous la barre
  -->
  <v-app-bar flat>
    <v-container class="d-flex align-center">
      <!--
      Bouton hamburger pour le tiroir de navigation (mobile)
        * Visible uniquement sur les petits écrans grâce à d-md-none
      -->
      <v-app-bar-nav-icon
        class="d-md-none"
        @click="drawer = !drawer"
      />

      <!-- Titre de l'application -->
      <v-toolbar-title>Pokédex</v-toolbar-title>

      <!--
      Liens de navigation (desktop uniquement)
        * d-none d-md-flex : cachés sur mobile, affichés à partir de md
      -->
      <v-btn
        v-for="link in menuItems"
        :key="link.title"
        :icon="link.icon"
        :to="link.path"
        class="d-none d-md-flex"
      />
    </v-container>
  </v-app-bar>

  <!--
  Tiroir de navigation (mobile)
    * v-model contrôle l'ouverture/fermeture
    * temporary : le tiroir se ferme automatiquement quand on clique ailleurs
  -->
  <v-navigation-drawer
    v-model="drawer"
    temporary
  >
    <v-list nav>
      <v-list-item
        v-for="link in menuItems"
        :key="link.title"
        :prepend-icon="link.icon"
        :title="link.title"
        :to="link.path"
        @click="drawer = false"
      />
    </v-list>
  </v-navigation-drawer>
</template>

<script setup>
/**
 * Éléments de menu pour la navigation
 * Chaque élément contient un titre, un chemin et une icône
 */
const menuItems = [
  { title: 'Accueil', path: '/', icon: 'mdi-pokeball' },
  { title: 'Favoris', path: '/favoris', icon: 'mdi-heart' },
  { title: 'À propos', path: '/a-propos', icon: 'mdi-information' },
]

/**
 * État du tiroir de navigation mobile
 */
const drawer = ref(false)
</script>

Commit

bash
git add -A
git commit -m "feat: navigation responsive avec tiroir mobile"

Projet perso — À faire en parallèle

Dans votre projet individuel :

  1. Ajoutez un v-navigation-drawer avec temporary
  2. Cachez les boutons desktop sur mobile avec d-none d-md-flex
  3. Ajoutez un v-app-bar-nav-icon visible uniquement sur mobile
  4. Testez en redimensionnant la fenêtre du navigateur

Documentation utile ​

Documentation pour les cours de développement web