vue route navigation guard

Posted by maniac1aw on Tue, 15 Feb 2022 14:15:20 +0100

As its name suggests, the navigation guard provided by Vue router is mainly used to guard navigation by jumping or canceling. There are many opportunities to implant in the routing navigation process:

  • Overall,
  • Exclusive to a single route,
  • Or component level.

Global guard

  • Global pre guard router beforeEach
  • Global resolution guard router beforeResolve
  • Global post hook router afterEach

Global front guard

You can use router Before each registers a global front guard:

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

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

Each guard method receives three parameters:

to: Route: the target route object to be entered

from: Route: the route that the current navigation is about to leave

next: Function: hook function, which defines parameters to confirm what to do in the next route

next('/') or next({path: '/'}): jump to a different address. The current navigation is interrupted and a new navigation is performed. You can pass any location object to next, next({name: 'home'}).

General applications redirect to / login when the user fails to authenticate:

router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
else next()
})
1234

Global resolution guard

In 2.5.0 +, you can use router Beforeresolve registers a global guard. This is similar to router Beforeeach is similar. The difference is that before the navigation is confirmed, and after the guard and asynchronous routing components in all components are parsed, the parsing guard is called

Global post hook

The difference is that the post hook will not accept the next function and will not change the navigation itself:

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

Route exclusive guard

You can directly define beforeEnter guard on routing configuration:

const router = new VueRouter({
routes: [
{
  path: '/foo',
  component: Foo,
  beforeEnter: (to, from, next) => {
    // ...
  }
}
]
})
1234567891011

The method parameters of these guards are the same as those of the global front guard.

Guard in assembly

The following route navigation guards can be defined directly in the route component:

  • Guard before grouping components beforeRouteEnter
  • Guard before routeupdate during route update (new in 2.2)
  • Guard when leaving the component beforeRouteLeave
const Foo = {
template: `...`,
beforeRouteEnter(to, from, next) {
// Before rendering the component, the corresponding route is called before confirm.
// no Yes! Get component instance ` this`
// Because the component instance has not been created before the guard executes
},
beforeRouteUpdate(to, from, next) {
// Called when the current route changes but the component is reused
// For example, for a path / foo/:id with dynamic parameters, when jumping between / foo/1 and / foo/2,
// Since the same Foo component will be rendered, component instances will be reused. The hook will be called in this case.
// Can access component instance ` this`
},
beforeRouteLeave(to, from, next) {
// Called when the navigation leaves the corresponding route of the component
// Can access component instance ` this`
}
}
123456789101112131415161718

beforeRouteEnter guard cannot access this because the guard is called before navigation confirmation, so the new component to be launched has not been created.

However, you can access the component instance by passing a callback to next. Execute the callback when the navigation is confirmed, and take the component instance as the parameter of the callback method.

beforeRouteEnter (to, from, next) {
next(vm => {
vm.$store.state.token
// Access component instances through 'vm'
})
}
123456

Note that beforeRouteEnter is the only guard that supports passing callbacks to the next. For beforeRouteUpdate and beforeRouteLeave, this is already available, so callback delivery is not supported because it is not necessary.

beforeRouteUpdate (to, from, next) {
// just use `this`
this.name = to.params.name
next()
}
12345

This exit guard is usually used to prevent users from leaving suddenly before saving their changes. The navigation can be cancelled by next(false).

beforeRouteLeave (to, from, next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
12345678

Complete navigation analysis process

  1. Navigation is triggered.
  2. Call beforeroutleave guard in the deactivated component.
  3. Call the global guard of each.
  4. Call beforeRouteUpdate guard (2.2 +) in the reused component.
  5. Call beforeEnter in the routing configuration.
  6. Resolve asynchronous routing components.
  7. Call beforeRouteEnter in the activated component.
  8. Call the global beforeResolve guard (2.5 +).
  9. Navigation confirmed.
  10. Call the global afterEach hook.
  11. Trigger DOM update.
  12. Call the callback function passed to next in beforeRouteEnter, and the created component instance will be passed in as the parameter of the callback function.

Topics: Javascript Front-end Vue.js