vue 路由守卫

vue-router 提供的导航守卫主要用来通过或取消的方式来守卫导航。有多种机会植入路由导航的过程:
主要分为全局导航,单个路由导航 组件导航

所谓路由导航我们可以这么理解,导航守卫就相当于保安的意思,你要进入这个房子,保安需要知道你是(to, from, next)打哪去,从哪来。我们就拿登录来就例子:保安守卫一个房子 有一个客人来拜访(路由跳转)保安要问清楚从哪来(from)到哪去(to) 问清楚以后他还要打电话给房子的主人问他是否允许进入(登录时获取token,如果有token 就是直接跳转详情页,如果没有token就跳转登录页)
我们先看vue 官网上面的解析

你可以使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ … })

router.beforeEach((to, from, next) => {
// …
})
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。

每个守卫方法接收三个参数:

to: Route: 即将要进入的目标 路由对象

from: Route: 当前导航正要离开的路由

next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

确保要调用 next 方法,否则钩子就不会被 resolved。
关于next()的理解

关于next这个方法的描述应该如何理解:

1 next()

你乘坐汽车要从A景区到B景区,路过关卡时,守门人拦下你,你量出了next(),守门人一看没问题,赶紧放行,于是你顺利到达了B景区。

2.next(false)

如果你量出了next(false),守门人立马关住大门,不让你走,哪都不让你去,你说想换个交通方式,走路或者坐飞机,都不行,老实待在A景区吧

3.next(’/’)

你原本打算从A景区到B景区,但是走到关卡的时候由于某些原因改变了主意,想要去C景区,你对守门员量出了next({path:’/C’}),守门员一看,哦,原来你不去B了,要去C啊,去吧去吧,然后你顺利到达了C景区

4.next(error)

你在出发之前,给你妈妈说,妈,要是有什么事我立马通知你,你记得查看消息啊(你注册了router.onError())走到中途,出现了意外,你发出next(error),然后你妈就收到了消息,赶紧打电话问你怎么了(执行router.onError()里的回调)

下面是一个全局导航(判断当前页面是否需要登录)

router.beforeEach ((to,from,next) => {
  //将所有需要登陆才显示的页面的路由都放进一个数组
  const nextRoute = ['index', 'library', 'design', 'administration', 'production'];
  //获取登陆状态
  let isLogin = Global.isLogin
 
  if(to.name === 'login') {  //如果是登录页,则跳过验证
    next()  //必不可少
    return  //以下的代码不执行
  }
  if(nextRoute.indexOf(to.name) >= 0) {  //判断该页面是否需要登陆
    if(!isLogin) {   //判断登陆状态
      next({ name : 'login'})   //如果未登录,则跳转到登录页
    } else {
      next()  //如果已经登陆,那就可以跳转
    }
  } else {  //其他的无需登陆的页面不做验证
      next()
  }

这样就实现了全局守卫

全局前置守卫

const router = new VueRouter({})
router.beforeEach(to,form,next) => {
// 当一个导航出发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫resolve 完之前一直处于等待中
})

全局后置守卫

我们也可以注册全局后置守卫和前置守卫不同的是,后置守卫中没有next()

router.afterEach((to, from) => {
alert("后置守卫")
})

路由独享守卫(单个路由导航)

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

const router = new VueRouter({
routes:[
 {
   path: '/foo',
   component: foo,
   beforeEnter: (to, from, next) => {
     let isLogin = Global.isLogin
     if(isLogin) {
       next()
     }else {
       next('./login')
     }
   }
 }]
})

组件内路由导航

// 跟methods: {}等同级别书写,组件路由守卫是写在每个单独的vue文件里面的路由守卫
beforeRouteEnter (to, from, next) {
// 注意,在路由进入之前,组件实例还未渲染,所以无法获取this实例,只能通过vm来访问组件实例
next(vm => {})
}
beforeRouteUpdate (to, from, next) {
// 同一页面,刷新不同数据时调用,
}
beforeRouteLeave (to, from, next) {
// 离开当前路由页面时调用
}

beforeRouteEnter: (to, from, next) => {
    next(vm => {
      alert("hello" + vm.name);
    });
  }

  beforeRouteLeave(to, from, next) {
    if (confirm("确定离开吗?") == true) {
      next();
    } else {
      next(false);
    }
  }

这个大概就是我要说的内容,现在还有几点我们需要注意

路由存在的问题

1第一种

iif (to.path === '/warranty-stepThree') {
    if (sessionStorage.getItem('oneStep') && sessionStorage.getItem('twoStep')) {
      next('/warranty-stepThree) // 直接死循环
    } else {
      next('/warranty')
    }

this 的问题

在组件路由导航中
路由前置守卫中
当前组件实例还没有渲染 不能够直接调用this 需要用next(vm => {}) 来替代

 next(vm => {
      alert("hello" + vm.name);
    });

参考文章
https://blog.csdn.net/zezeadede555/article/details/88380767
https://www.cnblogs.com/listen9436/p/10472483.html
https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E5%90%8E%E7%BD%AE%E9%92%A9%E5%AD%90

发布了35 篇原创文章 · 获赞 4 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览