阅读 797

路由守卫的分类和使用场景

分类

路由守卫: 是router对象一个属性,本质上是一个函数。在路由切换时,它会被调用,用它就可以用来去检查凭证(是否登录)

按执行的时机,定义的位置:

  1. 组件内的守卫
  2. 全局守卫
  3. 路由独享的守卫

执行时机

image-20210614202849029.png

使用

组件内的守卫

组件并不是任意组件,而是路由级别的组件

const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}
复制代码

参数说明:

  • to 表示在当前路由变化时,你进入哪个路由。
  • from 表示在当前路由变化时,你要离开哪个路由。
  • next 它是一个函数,你必须要调用这个next()来结束对当前的动作的处置。你可以根据自己的业务逻辑来决定使用如下三个中的某一个:
    • next() // 正常放行
    • next(false) // 不让跳,回去原来的页面
    • next(路由) 进入指定路由
      • next({path: , name:, ....})
      • next('/地址')

路由独享的守卫

你可以在路由配置上直接定义 beforeEnter 守卫

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

与全局前置守卫的方法参数是一样

全局守卫

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

router.beforeEach(function (to, from, next) {
  console.log('路由变化了', to, from, next)
  next()
})

router.afterEach(function (to, from) {
  console.log('路由变化了', to, from)
  next()
})
复制代码
beforeRouteLeave (to, from, next) {
  if (this.msg && window.confirm('确定要跳转')) {
    next()
  } else {
    next(false)
  }
},
复制代码

路由守卫的应用场景

离开页面时弹出提示窗口

image-20210614210301802.png

beforeRouteLeave (to, from, next) {
  if (this.msg && window.confirm('确定要跳转')) {
    next()
  } else {
    next(false)
  }
},
复制代码

动态路由跳转

article/1234 --> article/2345

例如:文章详情页

beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
    next()
    this.加载详情()
}
复制代码

使用全局守卫进行权限校验

用户没有登陆,他还想去访问个人中心页,让他回去登录

image-20210615093837106.png

操作

在router/index.js中补充一个前置路由守卫。业务逻辑有两条是:

  1. 如果没有登陆就不能访问某些敏感页面
  2. 如果登陆了,就不能再访问login页面
import store from '@/store/index.js'
const vipList = ['/setting']
router.beforeEach((to, from, next) => {
  const token = store.state.tokenInfo.token
  console.log(token)
  if (!token && vipList.includes(to.path)) {
    console.log('没有权限,不能访问vip页面')
    next('/login)
  } else if (token && to.path === '/login') {
    console.log('已经登录了,就不能访问login了')
    next('/')
  } else {
    next()
  }
})
export default router
复制代码

注意

  • 获取token动作应该在每次路由跳转都去做(代码要写在beforeEach内)
  • 把需要权限的页面写在一个数组中,方便我们使用includes方法进行判断
文章分类
前端
文章标签