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
// 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 liensrouter.push()
pour la navigation en javascript- La propriété
to
dans les composants Vuetify (ex:v-btn
) si disponible
💻 Exemple
<template>
<RouterLink to="/login">Se connecter</RouterLink>
<v-btn to="/contact">Contact</v-btn>
</template>
<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
:
<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
{
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
// 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.
// 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.
// src/pages/mon-compte.vue
<script setup>
export default {
meta: { requiresAuth: true }
}
</script>
Puis, dans un guard global, on fait la vérification.
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 tableauprotectedRoutes
selon la méthode choisie - Rediriger vers
/login
avec unequery.redirect
pour retourner automatiquement après connexion - Centraliser la logique d’authentification dans un
beforeEach()
propre