Skip to content

Vue Router (auto-routing) ​

Vue Router permet de gérer la navigation entre les pages dans une application Vue.js.

Dans nos projets, nous utilisons le plugin unplugin-vue-router qui génère automatiquement les routes à partir des fichiers dans le dossier src/pages.

1. Routage automatique ​

📘 Documentation ​

🎯 Objectif ​

Créer automatiquement les routes à partir de la structure des fichiers dans src/pages.

💡 Utilité ​

Plus besoin de déclarer manuellement les routes dans un tableau, elles sont créées dynamiquement.

📁 Exemple de structure ​

src/
└── pages/
    ├── index.vue          → route `/`
    ├── login.vue          → route `/login`
    ├── about.vue          → route `/about`
    └── pokemons/
        ├── index.vue      → route `/pokemons`
        └── [id].vue       → route dynamique `/pokemons/:id`

✅ Nomenclature à respecter ​

  • index.vue → devient la page racine du dossier
  • [param].vue → crée une route dynamique avec :param
  • [...all].vue → route catch-all (non utilisée dans tous les projets)
  • [...path].vue → toutes les autres routes qui n'ont pas de nom défini => 404 Not Found

2. Création manuelle des routes ​

Même si le routage automatique est pratique, il est toujours possible (et parfois nécessaire) de définir les routes manuellement.

💻 Exemple minimal ​

js
// src/router/index.js

// Importation des fonctions de base de Vue Router
import { createRouter, createWebHistory } from 'vue-router'

// Importation manuelle des composants utilisés comme pages
import Home from '@/pages/index.vue'
import Login from '@/pages/login.vue'

// Déclaration manuelle des routes (chemin + composant associé)
const routes = [
  // Route de la page d'accueil
  { path: '/', component: Home },

  // Route vers la page de connexion
  { path: '/login', component: Login },

  // Route dynamique pour les Pokémon (id variable dans l'URL)
  // Le composant est importé uniquement au moment où il est nécessaire (lazy loading)
  { path: '/pokemons/:id', component: () => import('@/pages/pokemons/[id].vue') }
]

// Création de l'instance du routeur avec un historique HTML5 (URL propres sans #)
export const router = createRouter({
  history: createWebHistory(), // utilisation de l'historique natif du navigateur
  routes // tableau de routes à utiliser
})

✅ Bonnes pratiques ​

  • Utiliser () => import(...) pour le lazy loading
  • Garder le nom des composants cohérent avec les routes
  • Ajouter meta pour les routes protégées

3. Navigation entre pages ​

Pour naviguer entre les pages, tu peux utiliser :

  • <RouterLink> pour les liens
  • router.push() pour la navigation en javascript
  • La propriété to dans les composants Vuetify (ex: v-btn) si disponible

💻 Exemple ​

vue
<template>
  <RouterLink to="/login">Se connecter</RouterLink>
  <v-btn to="/contact">Contact</v-btn>
</template>
vue
<script setup>
import { RouterLink, useRouter } from 'vue-router'

const router = useRouter()

function allerVersAccueil() {
  router.push('/')
}
</script>

✅ Bonnes pratiques ​

  • Utiliser <RouterLink> pour la navigation visible (liens)
  • Utiliser router.push() pour une navigation programmatique (ex : après une action)
  • Utiliser to pour les composants Vuetify qui le supportent (ex : v-btn)

4. Routes dynamiques ​

Les routes dynamiques permettent d'afficher une page selon un identifiant.

Exemple auto-routing ​

src/pages/pokemons/[id].vue  →  /pokemons/:id

Dans [id].vue :

vue
<script setup>
  // Importation du composable fourni par Vue Router
  // qui permet d’accéder à la route active (URL actuelle)
  import { useRoute } from 'vue-router'

  // Création d’une référence à l’objet route
  // Cet objet contient les informations sur la route courante (params, query, etc.)
  const route = useRoute()

  // Accès à un paramètre dynamique nommé `id` depuis l’URL
  // Exemple d’URL : /pokemons/25 → id = '25'
  const id = route.params.id
</script>

Exemple route manuelle ​

js
{
  path: '/pokemons/:id',
  name: 'PokemonDetail',
  component: () => import('@/pages/pokemons/[id].vue')
}

✅ Bonnes pratiques ​

  • Utiliser route.params.id pour accéder à l’ID dynamique
  • Toujours tester la présence de l’ID et gérer les erreurs si besoin (ex: id invalide)

5. Protéger l’accès avec un guard ​

📘 Documentation ​

Dans ton projet, certaines pages doivent être accessibles uniquement aux utilisateurs authentifiés. Pour cela, on peut utiliser des guards (gardiens de navigation). Voici comment faire selon que tu utilises l'auto-routage ou le routage manuel.

Avec auto-routage et tableau de routes protégées ​

Pour protéger certaines routes générées automatiquement, on peut définir un guard global dans router/index.js et une liste, tableau des chemins protégés manuellement.

💻 Exemple ​

js
// src/router/index.js

// Importe la fonction pour créer un routeur avec détection automatique des routes
import { createRouter, createWebHistory } from 'vue-router/auto'

// Importe la liste des routes automatiquement générée à partir de /src/pages
import { routes } from 'vue-router/auto-routes'

// Création de l’instance du routeur avec historique HTML5 (URL sans #)
const router = createRouter({
  history: createWebHistory(),
  routes, // routes générées automatiquement
})

// Liste manuelle des chemins devant être protégés (accès réservé aux utilisateurs connectés)
const protectedRoutes = ['/dashboard', '/profil']

// Guard global exécuté avant chaque navigation
router.beforeEach((to, from, next) => {
  const isAuthenticated = false // Remplacer par ta logique réelle (ex: store.token, authStore.user)

  // Si la route demandée est protégée et que l'utilisateur n’est pas authentifié
  if (protectedRoutes.includes(to.path) && !isAuthenticated) {
    next('/login') // Redirection vers la page de connexion
  } else {
    next() // Autorise la navigation
  }
})

// Exporte l’instance du routeur pour l’utiliser dans l’application
export default router

Avec routage manuel et métadonnées ​

Quand on fait du routage manuel, on peut ajouter une métadonnée requiresAuth dans la déclaration de la route. Par exemple, pour protéger la route /dashboard.

Dans le guard, si la route a requiresAuth à true, on vérifie si l'utilisateur est authentifié avant de lui permettre d'accéder à la page.

js
// src/router/index.js

// Définition des routes manuellement
const routes = [
  {
    path: '/dashboard', // Chemin de la route protégée
    component: () => import('@/pages/dashboard.vue'), // Chargement paresseux du composant
    meta: { requiresAuth: true } // Indique que cette route nécessite une authentification
  },
  // autres routes...
]

// Guard global : s'exécute avant chaque changement de page
router.beforeEach((to, from, next) => {
  const store = getAuthStore() // Récupère l'état d'authentification (via Pinia ou autre store)

  // Si la route nécessite l’authentification et que l’utilisateur n’est pas connecté
  if (to.meta.requiresAuth && !store.token) {
    next('/login') // Redirige vers la page de connexion
  } else {
    next() // Autorise la navigation
  }
})

🛡️ Avec auto-routage et métadonnées ​

On peut aussi utiliser la méthode des métadonnées avec le routage automatique.

Pour ce faire, il faut ajouter une propriété meta dans le fichier de la page.

js
// src/pages/mon-compte.vue
<script setup>
export default {
  meta: { requiresAuth: true }
}
</script>

Puis, dans un guard global, on fait la vérification.

js
router.beforeEach((to, from, next) => {
  const user = getAuthStore().user

  // Vérifie si la route nécessite une authentification
  if (to.meta.requiresAuth && !user) {
    next('/login') // Redirige vers la page de connexion
  } else {
    next() // Autorise la navigation
  }
})

🔍 Ce beforeEach s’exécute avant chaque changement de route.

✅ Bonnes pratiques ​

  • Utiliser meta.requiresAuth ou un tableau protectedRoutes selon la méthode choisie
  • Rediriger vers /login avec une query.redirect pour retourner automatiquement après connexion
  • Centraliser la logique d’authentification dans un beforeEach() propre

Documentation pour les cours de développement web