“Navigation” indicates that the route is being changed

Vue-router provides navigation guards that are used to guard navigation by jumping or canceling. There are multiple opportunities to implant routing during navigation, and they fall into three categories:

  • global
    • router.beforeEach
    • router.beforeResolve
    • router.afterEach
  • This parameter is exclusive to a single route
    • beforeEnter
  • The component level
    • beforeRouteEnter
    • beforeRouteUpdate
    • beforeRouteLeave

Note: Changes in parameters or queries do not trigger entry/exit navigational guards (you can deal with these changes by observing the $route object or using the component internal guard of beforeRouteUpdate).

To give you an intuition:

Global front guard

You can register a global front-guard using router.beforeeach

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

router.beforeEach((to, from, next) => {
  // ...
})
Copy the code

When a navigation is triggered, the global front-guard is called in the order it was created. The guard resolves asynchronously, in which case the navigation waits until all the guards resolve

parameter

Each guard method takes three arguments:

  • to:Route: Indicates the destination route object to be entered
  • from:Route: Current navigation is about to leave the route
  • next:FunctionBe sure to call this methodresolveThis hook. Execution effect dependencenextMethod invocation parameters
    • next()Proceed to the next hook in the pipe. If all hooks are executed, the navigation state is confirmed.
    • next(false): interrupts current navigation. If the browser URL changes (either manually by the user or by the browser back button), the URL is reset tofromIndicates the IP address of the route.
    • next('/')ornext({ path: '/' }): Jumps to a different address. The current navigation is interrupted and a new navigation is performed. You can asknextPass an arbitrary position object and allow setting such asreplace: true,name: 'home'And any other options used inrouter-linkto proprouter.pushIn.
    • next(error): (2.4.0+) If passednextThe navigation is aborted and the Error is passed torouter.onError()Registered callback.

Make sure to callnextMethod, otherwise the hook will not be resolved

Global parsing guard

You can register a global guard with router.beforeResolve. This is similar to router.beforeeach, except that the parse guard is called before the navigation is confirmed and after all the intra-component guards and asynchronous routing components are parsed.

Global post-hook

You can register a global post-hook, however unlike the guard, these hooks do not accept the next function nor change the navigation itself

router.afterEach((to, from) => {
  // ...
})
Copy the code

Route exclusive guard

You can define the beforeEnter guard directly on the route configuration:

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

These guards have the same method parameters as the global front-guard.

Guards within components

Of course, you can also define the following route navigators directly within the routing component:

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
const Foo = { template: `... ', beforeRouteEnter (to, from, next) {// Called before rendering the corresponding route to the component is confirmed // that is, when entering the new component // cannot get the component instance 'this' // because before the guard executes, }, beforeRouteUpdate (to, from, next) {// Called when the current route changes but the component is being reused // For example, for a path with dynamic parameters /foo/:id, When jumping between /foo/1 and /foo/2, // renders the same foo component, so the component instance is reused. And the hook will be called in that case. // Call beforeRouteLeave (to, from, next) {// Call beforeRouteLeave (to, from, next) {Copy the code

The beforeRouteEnter guard cannot access this because the guard is called before navigation confirmation, so the upcoming new component has not yet been created.

However, you can access the component instance by passing a callback to Next. The callback is executed when the navigation is validated, and the component instance is taken as an argument to the callback method.

BeforeRouteEnter (to, from, next) {next(vm => {// access component instance through 'VM'})}Copy the code

Note that beforeRouteEnter is the only guard that supports passing a callback to Next. For beforeRouteUpdate and beforeRouteLeave, this is already available, so passing callbacks are not supported because they are not necessary.

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

BeforeRouteUpdate is called when the path changes

This departure guard is usually used to prevent the user from leaving suddenly without saving the changes. This 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) } }Copy the code

Complete navigation parsing process

1. Navigation is triggered. 2. Call away guard in inactivated component. 3. Call the global beforeEach guard. 4. Call the beforeRouteUpdate guard (2.2+) in the reused component. 5. Invoke beforeEnter in the route configuration. 6. Parse the asynchronous route component. 7. Call beforeRouteEnter in the activated component. 8. Call the global beforeResolve guard (2.5+). 9. Navigation is confirmed. 10. Call the global afterEach hook. 11. Trigger DOM updates. 12. Call the callback passed to Next in the beforeRouteEnter guard with the created instance.

Code sample

//Router definition vue. use(Router) const Router = new Router({... }) // Navguard route. beforeEach((to, from, next) => {console.log(" Navguard: beforeEach,"); next(); }) router.aftereach ((to, from) => {console.log(" navigation post: afterEach,"); }) router. BeforeResolve ((to, from, next) => {console.log(" Navigation parsing guard: beforeResolve,"); next(); })Copy the code

Component hook:

Export default {// hook beforeCreate(){console.log(" Component hook: beforeCreate"); }, created(){console.log(" component hook: created"); }, beforeMount(){console.log(" Component hook: beforeMount"); }, mounted(){console.log(" component hook: mounted"); }, beforeUpdate(){console.log(" component hook: beforeUpdate"); }, updated(){console.log(" component hook: updated"); }, beforeDestroy(){console.log(" component hook: beforeDestroy"); }, deStoryed (){console.log(" component hook: deStoryed "); }, beforeRouteEnter (to, from, next) {console.log(" Component internal guard: beforeRouteEnter,"); Next ()}, beforeRouteUpdate (to, from, next) {console.log(" Component internal guard: beforeRouteUpdate,"); Next ()}, beforeRouteLeave (to, from, next) {console.log(" Component internal guard: beforeRouteLeave,"); next() } }Copy the code

Order of execution output:

Navigation front guard: beforeEach Component internal guard: beforeRouteEnter Navigation parse guard: beforeResolve Navigation rear guard: afterEach component hook: beforeCreate Component hook: Created component hook: beforeMount Component hook: Mounted // Execute jump component internal guard: beforeRouteLeave Navigation front guard: beforeEach navigation parse guard: BeforeResolve Navigation afterguard: afterEach Component hook: beforeDestroyCopy the code

For information about the Vue component lifecycle and hook functions, please refer to my article “Vue Lifecycle and Hook Functions”.


^ _ <