使用vue-router beforEach实现判断用户登录跳转路由筛选功能


Posted in Javascript onJune 25, 2018

在开发webApp的时候,考虑到用户体验,经常会把不需要调用个人数据的页面设置成游客可以访问,而当用户进入到一些需要个人数据的,例如购物车,个人中心,我的钱包等等,在进行登录的验证判断,如果判断已经登录,则显示页面,如果判断未登录,则直接跳转到登录页面提示用户登录,今天就来分享下如何使用vue-router的beforEach方法来实现这个需求。

实现

本篇文章默认您已经会使用 webpack 或者 vue-cli 来进行环境的搭建,并且具有一定的vue基础,如果您目前是一个新手,那么网上搜索一下就好,相关文章非常多,这里就不再赘述了。 话不多说,直接上代码。 为了方便日后代码的可维护性,我把相关方法写在了一个新建的filter.js文件里

使用vue-router beforEach实现判断用户登录跳转路由筛选功能 

接下来进入filter.js文件中,首先引入vue-router: import router from "./router"; 然后我们使用 router.beforEach 方法:

router.beforeEach((to, from, next) => {
  //根据字段判断是否路由过滤
  if (to.matched.some(record => record.meta.auth)) {
    if (getToken() !== null) {
      next()
    } else {
      //防止无限循环
      if (to.name === 'login') {
        next();
        return
      }
      next({
        path: '/login',
      });
    }
  } else {
    next()//若点击的是不需要验证的页面,则进行正常的路由跳转
  }
});

beforEach其实是vur-router的钩子函数,可以理解为每个router跳转之前都会调用的一个方法,既然有before同理当然也有afterEach,这个我们以后再讲。

首先来解释下beforEach的三个参数:

  • to:router即将进入的路由对象。
  • from:当前导航正要离开的路由。
  • 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可以通过query传递参数。
  • next(error) : (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

说明

好了,看到这里可能有些人还是没有理解,没关系,接下来我举个例子就可以明白了。

假设我们目前有三个路由: /home,/mine,/login

我们初始进入为 /home ,这时候点击跳转 /mine ,但是由于我们没有登录,所以会自动跳转到 /login
在以上这种情况下,

to:代表着路由 /mine ,我们要进入的路由。

from:代表着路由 /home ,我们将要离开的路由。

注意,使用beforEach最后必须要调用 next() ,否则会报错,如果不传参数,我们就会成功进入到 /mine ,如果我们传递参数,例如 next('/login') ,那么我们在点击任何路由都会跳转到 /login 界面。

但是我们的需求是只有点击需要进行登录验证的页面才进行拦截跳转,因此,我们需要加一些判断条件来进行路由的筛选。

if (to.matched.some(record => record.meta.auth)) {
    if (getToken() !== null) {
      next()
    }
  }

这里的to就是上面讲的参数to, to.matched 是一个对象数组,里面有to指向路由的相关信息,例如:path,name,meta等等。

我们用该数组调用some()方法根据返回值 true 或者 false 来进行判断,所以我们要在router.js路由配置文件中为我们需要验证登录判断跳转的路由添加一个字段来作为判断条件

{
   path: '/mine',
   name: 'mine',
   component: mine,
   meta:{auth:true} //我们自己添加的字段
  }

由于给路由添加了 meta:{auth:true} ,所以我们的 to.matched.some(record => record.meta.auth) 会返回 true ,这时我们就可以做登录判断了,我的项目是通过把token存入到 localstorage 来进行判断的, getToken()是我封装的一个获取 localstorage 方法。

if (getToken() !== null) {
      next()//若token不为null,则进行路由跳转
    }

如果没有token,我们下一步继续进行判断,也就是最终目的,进行路由拦截,跳转到登录页

else {
      next({
        path: '/login',
      });
    }

但是这时候我们会遇到新的问题,打开控制台会发现路由会无限的循环并最终崩溃,这是什么原因呢?仔细阅读上文红色加粗,我们可以理解为

next()
next({ path: '/login', });

也就是说beforeEach()必须调用next(),否则就会出现无限循环

next() 和 next('xxx') 是不一样的,区别就是前者不会再次调用router.beforeEach(),后者会。而由于我们没有token,所以在重新调用router.beforeEach()后,会再次进入到

else {
      next({
        path: '/login',
      });
    }

所以造成了无限循环,解决这个问题的方法也很简单,我们在 next({ path: '/login', }); 之前增加一个判断条件

if (to.name === 'login') {
        next();
        return
    }

如果我们to的定向路由 name == 'login' ,则执行 next(); 并return终止代码运行。

以上就是通过router.beforEach方法进行路由拦截了,我们不仅仅可以只做登录判断,通过这个方法可以实现很多需求,只要是有关路由跳转的都可以,在下只是抛砖引玉,如果有哪里不对的地方或者有更好的方法可以直接在评论告诉我,非常感谢。

总结

以上所述是小编给大家介绍的使用vue-router beforEach实现判断用户登录跳转路由筛选,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
使用IE的地址栏来辅助调试Web页脚本
Mar 08 Javascript
JSP跨iframe如何传递参数实现代码
Sep 21 Javascript
jQuery取id有.的值的方法
May 21 Javascript
js实现鼠标感应向下滑动隐藏菜单的方法
Feb 20 Javascript
妙用Bootstrap的 popover插件实现校验表单提示功能
Aug 29 Javascript
JS+CSS3制作炫酷的弹窗效果
Nov 08 Javascript
js继承实现方法详解
Dec 16 Javascript
微信小程序利用co处理异步流程的方法教程
May 20 Javascript
小程序图片长按识别功能的实现方法
Aug 30 Javascript
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
Sep 11 Javascript
Net微信网页开发 使用微信JS-SDK获取当前地理位置过程详解
Aug 26 Javascript
快速解决element的autofocus失效问题
Sep 08 Javascript
使用vue的transition完成滑动过渡的示例代码
Jun 25 #Javascript
JS实现仿微信支付弹窗功能
Jun 25 #Javascript
vue.js 实现输入框动态添加功能
Jun 25 #Javascript
vue-router重定向不刷新问题的解决
Jun 25 #Javascript
JavaScript实现封闭区域布尔运算的示例代码
Jun 25 #Javascript
详解React之父子组件传递和其它一些要点
Jun 25 #Javascript
Vue EventBus自定义组件事件传递
Jun 25 #Javascript
You might like
Zend studio for eclipse中使php可以调用mysql相关函数的设置方法
2008/10/13 PHP
php中神奇的fastcgi_finish_request
2011/05/02 PHP
通过dbi使用perl连接mysql数据库的方法
2014/04/16 PHP
yii实现级联下拉菜单的方法
2014/07/31 PHP
php实现无限级分类(递归方法)
2015/08/06 PHP
PHP单元测试框架PHPUnit用法详解
2019/01/23 PHP
php查询内存信息操作示例
2019/05/09 PHP
转换字符串为json对象的方法详解
2013/11/29 Javascript
在js文件中写el表达式取不到值的原因及解决方法
2013/12/23 Javascript
Vue.js动态添加、删除选题的实例代码
2016/09/30 Javascript
javascript 正则表达式分组、断言详解
2017/04/20 Javascript
详解微信小程序调用支付接口支付
2019/04/28 Javascript
Python中使用glob和rmtree删除目录子目录及所有文件的例子
2014/11/21 Python
从Python程序中访问Java类的简单示例
2015/04/20 Python
Python中turtle作图示例
2017/11/15 Python
Android基于TCP和URL协议的网络编程示例【附demo源码下载】
2018/01/23 Python
python判断输入日期为第几天的实例
2018/11/13 Python
梅尔频率倒谱系数(mfcc)及Python实现
2019/06/18 Python
Django 导出项目依赖库到 requirements.txt过程解析
2019/08/23 Python
tensorflow实现打印ckpt模型保存下的变量名称及变量值
2020/01/04 Python
深入了解Python enumerate和zip
2020/07/16 Python
selenium+python实现基本自动化测试的示例代码
2021/01/27 Python
Python LMDB库的使用示例
2021/02/14 Python
HTML5中Canvas与SVG的画图原理比较
2013/01/16 HTML / CSS
美国在线鲜花速递:ProFlowers
2017/01/05 全球购物
美国流行背包品牌:JanSport(杰斯伯)
2018/03/02 全球购物
W Hamond官网:始于1979年的钻石专家
2020/07/20 全球购物
delegate与普通函数的区别
2014/01/22 面试题
EJB需直接实现它的业务接口或Home接口吗,请简述理由
2016/11/23 面试题
营销与策划应届生求职信
2013/11/04 职场文书
蓬莱阁导游词
2015/02/04 职场文书
老公出轨后的保证书
2015/05/08 职场文书
电影小兵张嘎观后感
2015/06/03 职场文书
新郎父亲婚礼致辞
2015/07/27 职场文书
小学生纪律委员竞选稿
2015/11/19 职场文书
将MySQL的表数据全量导入clichhouse库中
2022/03/21 MySQL