Detailed explanation of vue router navigation hook of navigation guard

  • 2021-09-11 19:30:47
  • OfStack

When doing vue project, users are required to log in before visiting the page or send a reminder before leaving the page. The official route manager provided by vue, the navigation hook provided by vue-router, guards the navigation by jumping or canceling. The following summarizes the usage of the routing hook function and some usage scenarios.

1. Global Guard

router. beforeEach hook before route change


const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
 ... ...
})

Among them:

to: The path to be accessed from: Represents which path to jump from next: Is a function that indicates release. There are several ways to call next (): If 1 is normal, call this method to enter the next 1 hook; next (false): Interrupt the current navigation, that is, the routing address does not change; next ('/xxx') or next ({path: '/xxx'}): Force a jump to the specified path; next (error): If an Error instance is passed in, the navigation is interrupted and the error is passed to the registered callback of router. onError ().

Use:

Using this function, 1 must call next (), otherwise the hook function cannot resolve;

This method is commonly used to verify user access rights.

For example, a system needs to verify whether the user is logged in first, and if it is logged in, it can be accessed, otherwise it will jump directly to the login page. The specific implementation is as follows:


import Vue from 'vue'
import VueRouter from 'vue-router'
import { getToken } from '@Utils/session.utils' //  Login user's token
import Login from '../pages/Login.vue' // Introducing a login page 
const Home = () => import('../pages/Home.vue') // Introducing Home Page 

Vue.use(VueRouter) //  Global injection router

//  Configure routing parameters 
const routes = [
 { path: '/login', name: 'login', component: Login },
 { path: '/home', name: 'home', component: Home }
]

const router = new VueRouter({
 routes
})

//  Globally mount the routing navigation guard: verify whether the user is logged in 
router.beforeEach((to, from, next) => {
 if (to.name !== 'login' && !getToken()) next('/login') //  Force a jump to the login page if the user is not accessing the login page and is not logged in 
 else next()
})

export default router

router. beforeResolve This hook function is called before the navigation is validated and after the guard and asynchronous routing components within all components are resolved.
I haven't used this method in the project for the time being. Please add the specific use scenario:)

router. afterEach Hook after route change


router.afterEach((to, from) => {
 ... ...
})

This method differs from the global front guard router. beforeEach in that it lacks the next () function and does not change the navigation itself.

Usage scenario:

Routing, returning the scrolling position of the page to the top.

For example, 1 page is relatively long. When you scroll to a certain position, switch routes. At this time, the scroll bar position of the jumped page defaults to the position where the previous page stayed when leaving. You can reset the scroll bar position through this hook function.


//  Switch the route and the page returns to the top 
router.afterEach((to, from) => {
 window.scrollTo(0, 0)
})

2. Routing Exclusive Guards

An beforeEnter individual guard for a route, defined directly on the route configuration


const routes = [
 { path: '/login', name: 'login', component: Login },
 { 
  path: '/home', 
  name: 'home', 
  component: Home,
  beforeEnter: (to, from, next) => {
   ... ...
  }
 }
]

const router = new VueRouter({
 routes
})

Use:

The parameter usage of this method is the same as that of global front guard router. beforeEach;
For example, different modules are displayed according to different roles of logged-in users; Or add a separate animation to the specified routing component.


import Vue from 'vue'
import VueRouter from 'vue-router'
import { getUserRole } from '@Utils/session.utils' //  The role of the logged-in user 

const UserCenter = () => import('../pages/UserCenter.vue')

const routes = [
 ... ...
 { 
  path: '/usercenter', 
  name: 'usercenter', 
  component: UserCenter,
  beforeEnter: (to, from, next) => {
   if(getUserRole() === 'admin') next('/admincenter')
   else next()
  }
 }
]

3. Guards inside the component

beforeRouteEnter (to, from, next) is called before entering the route corresponding to the current component


export default {
 data() { ... },
 beforeRouteEnter(to, from, next) {
  ... ...
 }
}

Note:

The current component instance this cannot be accessed in this function because the function is called before the corresponding route is comfirm, and the component instance to be rendered has not been created at this time;

The component instance can be accessed by passing a callback to next, that is, the component instance vm is taken as the parameter of the callback method; The callback is executed after mounted;


beforeRouteEnter (to, from, next) {
 next(vm => {
  //  Pass  vm  To access the component instance 
 })
}

beforeRouteEnter is the only guard that supports passing callbacks to next.

Usage scenario:

For example, enter the details page from one list page, and then return to the list page, requiring to keep the data and scrolling position accessed before leaving the list page, and re-enter the list page from other pages to get the latest data. Please click here for specific implementation
beforeRouteUpdate (to, from, next) is called when the current route changes, but the component is reused


beforeRouteUpdate (to, from, next) {
 ... ...
}

Note:

The current component instance this can be accessed within this function

For example, when a path with dynamic parameters/detail/: id jumps between/detail/aaa and/detail/bbb, because both routes render the same Detail component, the original component instance will be reused (reuse is more efficient than destroy and re-create), in which case this hook will be called, and the component life cycle hook will not be called again.

beforeRouteLeave (to, from, next) is called before leaving the corresponding route of the current component


beforeRouteLeave (to, from, next) {
 ... ...
}

Note:

The current component instance this; can be accessed within this function; For example, the user suddenly leaves when there is unsaved content on the current page, prevents the page from jumping and gives a prompt, or clears or stores some information when the user leaves.

4. Complete navigation parsing process

Navigation is triggered; Invoke beforeRouteLeave guards in inactive components; Call the global beforeEach guard; Calling beforeRouteUpdate Guard (2.2 +) in reused components; Call beforeEnter in routing configuration; Parsing asynchronous routing components; Invoke beforeRouteEnter in the activated component; Call the global beforeResolve guard (2.5 +); Navigation is confirmed; Call the global afterEach hook; Trigger DOM update; Call the callback function passed to next in the beforeRouteEnter guard, and the created component instance will be passed in as an argument to the callback function.

In fact, there are only a few commonly used ones. After understanding their usage, the analysis process of routing navigation will be clear.

5. Attachment: Monitoring routing changes using watch

In addition to using the hook function, we can also use watch to listen to the $route object and then respond to changes in routing parameters.


import Vue from 'vue'
import VueRouter from 'vue-router'
import { getToken } from '@Utils/session.utils' //  Login user's token
import Login from '../pages/Login.vue' // Introducing a login page 
const Home = () => import('../pages/Home.vue') // Introducing Home Page 

Vue.use(VueRouter) //  Global injection router

//  Configure routing parameters 
const routes = [
 { path: '/login', name: 'login', component: Login },
 { path: '/home', name: 'home', component: Home }
]

const router = new VueRouter({
 routes
})

//  Globally mount the routing navigation guard: verify whether the user is logged in 
router.beforeEach((to, from, next) => {
 if (to.name !== 'login' && !getToken()) next('/login') //  Force a jump to the login page if the user is not accessing the login page and is not logged in 
 else next()
})

export default router

0

Related articles: