Vue 导航守卫

2,717 阅读3分钟

一、什么是导航守卫?

导航:“导航”表示路由正在发生改变。

二、为什么使用导航守卫?

真实的项目中需要判断权限或者登录状态决定用户能访问的路由,但是因为路由是在浏览器地址栏中的,用户可以输入,如果不加以拦截就可以看到本不该看到的页面;为了避免这种情况,我们需要使用导航守卫,在路由发生变化时作出相应的判断,判断用户是否可以去到他想去往的页面的路由;

三、常用的导航守卫:

    let router = new VueRouter({....});

1.全局前置守卫

    router.beforeEach((to, from, next) => {....})
  • 当一个路由发生变化时(从一个页面跳到另一个页面时),就会触发beforeEach中得回调函数,该回调函数有三个参数:
  1. to 路由对象,即将进入的页面的路由信息
  2. from 路由对象,当前正要离开页面路由信息
  3. next 函数,交出控制权或者中断导航
    3.1 next() 交出控制权,执行下面的功能
    3.2 next(false) 中断当前导航,如果url改变了,将会回退到当前页面
    3.3 next('/') 跳转到另一个路由,next可以接收和$router.push()一样的参数
  • 当使用导航守卫时,无论是否通过验证,都要调用next方法,如果通过校验则执行next() ,不通过则重定向或者中断;如果不调用,那么整个路由变化处于挂起状态,无法渲染任何组件;

2. 路由独享守卫

  • 你可以在路由配置上直接定义 beforeEnter 守卫;
export default new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/about',
      name: 'about',
      component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
      beforeEnter (to, from, next) {
        console.log(to)
        console.log(from)
        next()
      }
    }
  ]
})
  • beforeEnter方法同样有三个参数,其3个参数和全局守卫的三个参数相同,在进入该路由组件之前都会调用该钩子,我们在这个钩子中进行校验,如果校验通过,则执行 next(),只有执行next,才能渲染该路由对应的组件;

3.组件内守卫

  • 最后,你可以在路由组件内直接定义以下路由导航守卫;
  • beforeRouteEnter 在渲染该组件的对应路由前调用,该钩子中不能访问this,因为实例还未创建
  • beforeRouteUpdate 在当前路由改变,但是该组件被复用时调用,适用于动态路由的参数发生变化时
  • beforeRouteLeave 导航离开该组件的对应路由时调用,即要从当前页面去往其他页面时调用,可以用来做保存拦截,例如提示用户信息尚未保存等;
export default {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}