The demo code is based on vue-Router 4.x
preface
How many hook functions does vue-router have? What is the specific and what is the implementation process?
Let’s start with mind mapping.
Analysis of the
Vue-router’s hook function is essentially a navigation guard.
Quote from the official website
Navigation indicates that the route is changing.
Vue-router provides navigation guards that are used to guard navigation by jumping or canceling. There are several opportunities for embedding route navigation: global, single route proprietary, or component level.
That is: global guard, route guard, component guard.
Code presentation environment setup
So let’s just set up the environment
index.js
/* * @description: A bird * @date: 2021-03-21 16:17:56 * @lasteditTime: 2021-07-18 15:14:42 * @filepath: \vite-project-js\src\router\index.js */
import { createRouter, createWebHashHistory } from 'vue-router';
const router = createRouter({
history: createWebHashHistory(),
routes: [{path: '/a'.component: () = > import('.. /components/A.vue'),}, {path: '/b'.component: () = > import('.. /components/B.vue'),}, {path: '/c'.component: () = > import('.. /components/C.vue'),},]});export default router;
Copy the code
main.js
// index.js
import router from "./router";
createApp(App).use(router).mount("#app");
Copy the code
A page
<template>
<div>
<h1>I'm page A</h1>
<comp></comp>
</div>
</template>
Copy the code
Page B
<template>
<div>
<h1>I'm page B</h1>
<comp></comp>
</div>
</template>
Copy the code
Page C
<template>
<div>
<h1>I'm page C</h1>
<comp></comp>
</div>
</template>
Copy the code
Common component
<template>
<div>I'm a common component</div>
</template>
Copy the code
The current page is a bit ugly, let’s see, we are not here to learn CSS
Global guard
As the name implies, the router object in our index.js is defined globally.
beforeEach
Global front-guard, which fires before a route jump, fires every time it navigates.
Register a global front-guard with router.beforeeach.
router.beforeEach((to, from, next) = > {
console.log('🚀 🚀 ~ to:', to);
console.log(' '🚀 🚀 ~ the from..from);
next();
})
Copy the code
parameter
BeforeEach The global front-guard receives three parameters
- To: Route: indicates the destination Route to be entered
- From: Route: Indicates the Route object that the current navigation is leaving
- Next: Function: This method must be called otherwise it will block the route.
Note: The next parameter may not be added, but once added, it must be called once, otherwise the route jump will stop and so on.
Several cases of the next () method
- Next (): Goes to the next hook in the pipe.
- next(false):Interrupts current navigation. Go back to
from
Indicates the IP address of the route. - Next (‘/’) or next({path: ‘/’}):Jump to a different address with passable parameters
router.push
Is consistent with. - next(error):The navigation terminates and the error is passed to
router.onError()
Registered callback.
Let’s print out the first two parameters, which contain the path, parameters, meta information and so on.
The return value
- False: Cancel the current navigation.
- Null, undefined, true or return: calls the next navguard.
Defining multiple guards
Multiple global front-guards can be defined and called in the order they were created. Navigation is waiting until all guards are complete.
In this example we define two global front-guards beforeEach. As you can see, the page jumps only after two seconds after each log is printed.
//index.js
router.beforeEach((to, from, next) = > {
setTimeout(() = > {
console.log('🚀 🚀 ~ beforeEach1');
next();
}, 1000);
});
router.beforeEach((to, from, next) = > {
setTimeout(() = > {
console.log('🚀 🚀 ~ beforeEach2');
next();
}, 1000);
});
Copy the code
With the exception of the beforeEach global front-guard, all global guards can have multiple definitions, and the navigation waits until all the guards are complete, other hook functions are not demonstrated.
beforeResolve
Global resolution guard, which is triggered after all component internal guards and asynchronous route components are resolved before a route jump, is also triggered during each navigation.
Register a global resolution guard with router.beforeResolve.
router.beforeResolve((to, from, next) = > {
next();
})
Copy the code
Callback argument, returns the same value as beforeEach. You can also define multiple global parse guards.
afterEach
Global rear hook that occurs after a route jump is complete, beforeEach and beforeResolve, and before beforeRouteEnter (component internal guard). It also fires every time you navigate.
AfterEach registers a global post-hook with router.aftereach.
router.afterEach((to, from) = > {
console.log('🚀 🚀 ~ afterEach:');
})
Copy the code
The two arguments to this hook are the same as to and from in beforeEach. Unlike other global hooks, however, these hooks do not accept the next function or change the navigation itself.
Routing guard
As the name implies, this is the hook associated with routing. We have only one routing guard, which is beforeEnter.
beforeEnter
You need to define the beforeEnter guard on the route configuration, which fires only when a route is entered, immediately after beforeEach, and not when params, Query, or hash changes.
//index.js
{
path: '/a'.component: () = > import('.. /components/A.vue'),
beforeEnter: (to, from) = > {
console.log('🚀 🚀 ~ beforeEnter'); }},Copy the code
BeforeEnter the parameters of the route guard are to, from, and next, as beforeEach.
Component guard
As the name implies, is a guard defined inside a routing component.
beforeRouteEnter
//A.vue
beforeRouteEnter(to, fromNext,) {
console.log('🚀 🚀 ~ beforeRouteEnter');
},
Copy the code
Called before the route enters the component, this hook is called after the global guard beforeEach and the route guard beforeEnter, and before the global beforeResolve and global afterEach.
Parameters include to, from, and next.
This guard can not access the component instance, meaning this is undefined, which means it is triggered before the beforeCreate life cycle.
beforeRouteUpdate
//A.vue
beforeRouteUpdate(to, from) {
console.log('🚀 🚀 ~ beforeRouteUpdate');
},
Copy the code
For beforeRouteUpdate, this is already available, so passing a callback to Next is unnecessary.
beforeRouteLeave
//A.vue
beforeRouteLeave(to, from) {
console.log('🚀 🚀 ~ beforeRouteLeave');
},
Copy the code
For beforeRouteLeave, this is already available, so passing a callback to Next is unnecessary.
conclusion
Complete navigation parsing process
- Navigation is triggered.
- Called in a deactivated component
beforeRouteLeave
The guards.- Call global
beforeEach
The guards.- Called in a reused component
beforeRouteUpdate
The guards.- Called in the routing configuration
beforeEnter
.- Parse the asynchronous routing component.
- Called in the active component
beforeRouteEnter
.- Call global
beforeResolve
The guards.- Navigation confirmed.
- Call global
afterEach
Hook.- The trigger
DOM
The update.- call
beforeRouteEnter
Guard passnext
The created component instance is passed in as an argument to the callback function.
The above is the official answer, now let’s use the flow chart to intuitively show.
reference
Vue-router official website