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