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

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

实现

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

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

转载于:https://www.cnblogs.com/wenqiangit/p/10338480.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,可以非常方便的实现单页面应用程序的路由功能。 Vue Router 提供了以下两种方式实现页面路由跳转: 1. 声明式导航:通过 `<router-link>` 组件实现页面跳转,该组件会被渲染成一个 `<a>` 标签,点击该标签后会触发路由跳转。 2. 编程式导航:通过 `$router` 对象提供的方法实现页面跳转,例如 `$router.push()`、`$router.replace()`、`$router.go()` 等方法。 下面我们来看一个简单的示例,在 Vue Router 中如何实现页面路由跳转: ```html <!-- 在模板中使用 router-link 组件 --> <router-link to="/home">Home</router-link> <!-- 在组件中使用 $router 对象实现编程式导航 --> <button @click="$router.push('/about')">About</button> ``` 在上面的示例中,我们分别演示了如何使用 `<router-link>` 组件和 `$router` 对象实现页面路由跳转,其中 `to` 属性表示跳转的目标路由地址。 此外,Vue Router 还支持路由嵌套的功能,可以通过嵌套路由的方式实现页面的嵌套展示。下面我们来看一个嵌套路由的示例: ```javascript const router = new VueRouter({ routes: [ { path: '/home', component: Home, children: [ { path: 'news', component: News }, { path: 'videos', component: Videos } ] } ] }) ``` 在上面的示例中,我们定义了一个名为 `Home` 的路由组件,并在该组件中嵌套了两个子路由 `News` 和 `Videos`,这样就可以实现在 `Home` 组件中展示新闻和视频内容的功能。在实际开发中,我们可以根据实际需求来定义不同的路由组件和子路由实现灵活的页面嵌套效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值