Skip to content

路由守卫

vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航

记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察$route对象来应对这些变化,或使用的组件内守卫, beforeRouteUpdate的组件内守卫。

全局前置守卫

router.beforeEach注册一个全局前置守卫,守卫按照创建顺序调用。守卫是,导航在守卫resolve之前都处于等待中。

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

router.beforeEach((to, from, next) => {
  // ...
})
  • to:Route 即将进入的路由对象
  • from:Route 导航离开前的路由
  • next:Function
    • next() 进入下一个钩子。钩子全执行完成,导航状态为confirmed
    • next(false) 中断当前导航。
    • next('/')/next({path:'/'}) 跳转到一个不同的地址,可指定路径
    • next(error) 导航会被终止,错误传递

全局解析守卫

router.beforeResolve和全局前置钩子类似,即导航被cofirmed之前,路由组件被解析之后。

全集后置钩子

router.afterEach,不会改变导航本身。

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

路由独享守卫

router.beforeEnter和前置守卫一样

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

组件内的守卫

beforeRouteEnter

在渲染该组件的对应被cofirmed前,不能使用this,组件实例还没被创建

plain
beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}

beforeRouteUpdate

路由改变前,组件被复用时调用,可以访问组件实例this

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

beforeRouteLeave

导航离开改组件对应路由时调用,可以访问组件实例this。

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

导航解析流程

  1. 导航触发
  2. 失活组件调用beforeRouteLeave
  3. 调用全局前置钩子beforeEach
  4. 重用组件调用beforeRouteUpdate
  5. 路由配置调用beforeEnter
  6. 解析异步路由组件
  7. 被激活组件中调用beforeRouteEnter
  8. 调用全局解析守卫beforeResolve
  9. 导航被确定
  10. 调用全局后置钩子afterEach
  11. 触发DOM跟新
  12. 调用beforeRouterEnter中的next回调

具体例子参考

路由懒加载

由于打包的时候包会很大,影响页面加载,可以通过路由对应的组件进行分割成不同的代码块。

plain
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

Vue Router