React
Guardie di navigazione in Vue Router: ordine e valori di ritorno
In Vue Router 4 una guardia restituisce un valore: false blocca, una rotta reindirizza, niente prosegue. L’ordine decide quale vince.
In sintesi
- Una guardia in Vue Router 4 restituisce un valore; next() è facoltativo.
- L’ordine è beforeEach, beforeEnter, beforeRouteEnter, beforeResolve, afterEach.
- Le guardie proteggono la navigazione, non i dati: il controllo server resta necessario.
Una guardia di navigazione in Vue Router 4 restituisce un valore: false annulla la navigazione, una rotta la reindirizza, nessun valore la lascia passare. La forma con next() resta supportata, ma mescolare le due nello stesso file è la causa più comune di redirect infiniti.
Ordine di esecuzione
| Fase | Dove si dichiara | Cosa può fare |
|---|---|---|
| beforeEach | router.beforeEach | Bloccare o reindirizzare ogni navigazione |
| beforeEnter | Sulla rotta | Vale solo per quella rotta |
| beforeRouteEnter | Nel componente | Entrare senza accesso a this |
| beforeResolve | router.beforeResolve | Ultimo controllo prima della conferma |
| afterEach | router.afterEach | Solo effetti: analytics, titolo |
L’ordine è quello della tabella. Conoscerlo evita il caso classico: lo stesso controllo di autenticazione scritto in beforeEach e in beforeEnter, che gira due volte senza motivo.
Autenticazione senza incoerenze
router.beforeEach(async (to) => {
const session = await getSession();
if (!session && to.meta.requiresAuth) {
return { name: "login", query: { next: to.fullPath } };
}
if (session && to.name === "login") {
return { name: "dashboard" };
}
});
La seconda condizione è quella che manca quasi sempre. Senza di essa un utente già autenticato può aprire la pagina di login: non è un loop, è uno stato incoerente che confonde chi sta usando l’app.
Bloccare l’uscita da un form
import { onBeforeRouteLeave } from "vue-router";
const dirty = ref(false);
onBeforeRouteLeave(() => {
if (!dirty.value) return true;
return window.confirm("Uscire senza salvare?");
});
onBeforeRouteLeave vale solo per il componente che lo dichiara. Restituire false annulla la navigazione e l’URL non cambia.
Errori che si vedono in produzione
- Guardia registrata dentro
setup(): si aggiunge un listener a ogni montaggio. next()chiamato due volte nella stessa guardia: la seconda chiamata viene ignorata con un avviso.- Redirect verso la rotta protetta senza controllare la sessione: loop.
- Guardia asincrona senza
awaitsulla sessione: la decisione arriva dopo la navigazione.
Il limite noto
Le guardie proteggono la navigazione, non i dati. Un client può chiamare l’API direttamente: ogni rotta protetta ha bisogno anche di un controllo sul server. La guardia serve all’interfaccia, non alla sicurezza.
Comandi
npm install vue-router@4
npx vue-tsc --noEmit
Dal catalogo: shadcn-vue, vue-bits e il blocco logo Vue. Le guide: le librerie UI per Vue 3 e la struttura di un progetto Nuxt 3; il confronto: Vue contro React nel 2026.
Domande frequenti
next() è ancora supportato?
Sì, ma conviene scegliere una forma sola. In una guardia asincrona restituisci il valore e non chiamare next.
Perché la mia guardia non vede lo store alla prima visita?
Perché gira prima del mount dell’app. Aspetta router.isReady() oppure inizializza lo store prima del mount.
Come faccio un redirect permanente?
Con una regola in createRouter, non con una guardia. La guardia girerebbe a ogni navigazione e aggiungerebbe lavoro inutile.
beforeRouteEnter è diverso da beforeEnter?
Sì. beforeEnter è una proprietà della rotta, beforeRouteEnter è un hook del componente e non ha accesso a this.
Posso annullare il tasto Indietro?
Sì, restituendo false da onBeforeRouteLeave sul componente attivo. Non puoi bloccare la chiusura della scheda.