Vue Router提供的路由守卫主要用来通过跳转取消的方式守卫导航。

在路由守卫中,你可以自定义何时何种情况放行拦截页面的路由。通过Vue Router,可以实现对前端页面路由的权限控制。

Vue 路由守卫有以下分类:

  • 全局守卫
  • 独享守卫
  • 组件内守卫

全局路由守卫

全局路由守卫,是在Router配置文件中,在router上配置的路由守卫。

在配置路由守卫之前,在Router配置文件中需要先接收到router实例:

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

全局路由守卫对整个Vue Router下的所有路由都生效。

全局前置守卫

全局前置路由守卫的使用方式如下:

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

router.beforeEach()需要传入一个回调函数。该回调函数的定义方式不限,可以使用function也可以使用Lambda。

router.beforeEach()回调函数可以接收到3个参数:

  1. to:记录跳转的目标路由信息(跳转到哪里)。对象类型,其中常用的属性如下:
  • to.path:路由的路径,字符串类型,返回的是真实的路由请求路径。
  • to.query:路由所携带的 Query 参数,以对象的形式呈现。
  • to.fullPath:全路径名,字符串类型,返回的是真实的路由请求路径,带有 Query 参数,而 to.path 不包含 Query 参数。
  • to.params:路由所携带的路径参数,以对象的形式呈现。
  • to.meta:获取路由元数据,元数据是定义在路由配置信息中,由程序员定义的一组路由信息。
  1. from:记录跳转的来源路由信息(从哪里跳转)。对象类型,结构与to相同。
  2. next(可选):传递给回调的函数,用来放行路由。在使用next()时,必须严格确保它在任何情况下最多只能被调用一次。否则,可能会引起错误。

要避免错误的发生,可以在调用next()之后调用return结束回调的执行,例如使用return next()

默认情况下,调用next()跳转到的是to参数中所指的路由(也就是用户选择跳转的路由)。

next()可以接收一个如下参数:

  • false:中断当前的导航。

  • path:字符串类型,指定最终跳转的路径。

  • to:对象类型,定义最终跳转的目标路由信息。

    也就是说,可以使用next(to)指定跳转到哪个具体路由。例如跳转到一个名为Login的路由可以使用next({ name: 'Login' });或者,通过路径指定跳转的目标路由,如next({ path: '/login' })

    这个to对象的结构与router.beforeEach()回调中的to参数对象结构不同。它更像是<router-link>中给to props传递的对象或传给$router.push()的配置对象。还可以在其中配置如paramsqueryreplace等信息。

  • Error实例(2.4.0+):导航会被终止且该错误会被传递给router.onError()注册过的回调。

全局前置路由守卫router.beforeEach()会在以下两种情况被调用:

  • 初始化时;
  • 每次路由切换完成之前。

全局后置钩子

全局后置钩子用来进行路由跳转后的处理。与守卫不同的是,钩子不会接受next函数也不会改变导航本身。

使用方式如下:

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

全局后置钩子router.afterEach()会在以下两种情况被调用:

  • 初始化时;
  • 每次路由切换成功之后。

如果路由切换不成功,例如在router.beforeEach()中调用了next(false)next(error)时,router.afterEach()不会被调用。

全局解析守卫

全局解析守卫(router.beforeResolve)是Vue Router 2.5.0新增的一种路由守卫。

router.beforeResolve()的用法与router.beforeEach()类似。

router.beforeResolve()注册的回调会在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后被调用。


独享路由守卫

独享路由守卫(beforeEnter)是在特定的路由配置下定义的,在进入该路由之前执行的一个函数。

beforeEnter()用法如下:

export default new VueRouter({
  routes: [
    {
      name: routerName,
      path: routerPath,
      component: Component,
      beforeEnter: (to, from, next) => {
        /* ... */
      },
    }
  ]
})

beforeEnter()的参数与router.beforeEach()回调的参数一致。


组件内路由守卫

组件内路由守卫有以下几种:

  • beforeRouteEnter:通过路由规则,进入该组件时被调用。

    beforeRouteEnter中不能获取组件实例this,这是因为在执行beforeRouteEnter时,组件实例可能还未被创建。

  • beforeRouteLeave:通过路由规则,将要离开组件时被调用。

  • beforeRouteUpdate(Vue Router 2.2 新增):在当前路由改变,但是该组件被复用时调用。

    例如在带有动态的路径参数改变时,由于会渲染同样的路由组件,所以实例会被复用。而这个钩子将在被复用时被调用。

通过其它非路由方式进入或呈现该组件,以上三个守卫都不会被调用。