Actualmente se espera que la navegación esté confirmada, por lo que tanto beforeEach como afterEach se activan las protecciones globales. Se supone que showSpinner y hideSpinner se llaman en pareja en cada navegación.
router.beforeEach((to, from, next) => { showSpinner(); next(); } router.afterEach((to, from) => { // This line can be never called hideSpinner(); }); Por lo que veo, el resultado de la navegación no está disponible hasta el next en guardias.
Luego, en otro lugar, la navegación se cancela, por lo que permanece en la ruta anterior, y afterEach no se activa (lo mismo probablemente se aplica al aborto de navegación):
beforeRouteEnter() { ... next(false); } El resultado es que afterEach y hideSpinner no se activan.
Esto sucede con Vue Router 3.4.9 y Vue 2.6.
¿Cómo se puede solucionar esto?
Parece que no hay una forma integrada de obtener un evento de cancelación de una navegación cancelada.
Sin embargo, al profundizar en el código vue-router , descubrí que cada transición a una ruta se maneja en router.history mediante la función transitionTo que acepta como tercer argumento una función de cancelación, que se llama cuando la navegación no ha sido confirmada. Es posible interceptar ese evento sobrescribiendo esta función.
Estoy seguro de que este código recibirá algunas críticas, pero tal vez esté aquí para generar algunas ideas.
const transitionTo = Object.getPrototypeOf(router.history).transitionTo; Object.getPrototypeOf(router.history).transitionTo = function (...args) { const abortFn = args[2] && new Function("return " + args[2].toString()); args[2] = (err) => { // eventBus.$emit("hide-spinner"); // or any other method to hide the spinner console.log("Aborted", err); abortFn && abortFn(err); }; transitionTo.apply(router.history, args); };Y aquí hay una caja de códigos de trabajo
Como entendí por su pregunta, desea que afterEach se active incluso cuando se cancela la navegación. Para responder mejor a la pregunta supongamos que tenemos una ruta Acerca de que en algunas condiciones se cancela la navegación a esta ruta. Como dice la documentación del enrutador Vue :
puede acceder a la instancia pasando una devolución de llamada a next. Se llamará a la devolución de llamada cuando se confirme la navegación, y la instancia del componente se pasará a la devolución de llamada como argumento.
Entonces, en la ruta Acerca de, podemos tener este código:
beforeRouteEnter(to, from, next) { next(vm => { // put your codes here, for example the condition that must be applied let condition = true; if (condition) { vm.$router.push(from.path); } }) } Al usar ese código en lugar de next(false) , en realidad cancelamos la navegación a Acerca de la ruta, pero en este caso también se activa afterEach .