返回顶部

Vue 路由拦截(对某些页面需要登陆才能访问)

前言

做项目的时候有个需求,就是发现没有登录,竟然也可以进入我的主页,这样肯定是不能容忍的。于是就要让他进入主页的时候,加个判断是否有登录,若没有登录,则返回登录界面,登录成功后还可以跳转到之前进入的页面;若登录,则爱点哪里就点哪里,也就是vue中的路由拦截。

PS:可能有点啰嗦,但是讲得还算清楚,若只想实现功能,直接复制代码去实战也可以啦,写这篇的时候是10.24,我们程序员的节日,先祝各位大佬节日快乐,无BUG,今晚实现这个功能也是很快乐的呢,特意写篇博客记录一下,希望能帮助到你们!

 

路由拦截其实很简单:1)加上meta。2)router.beforeEach函数加上判断即可,具体往下瞧哦~

接下来进入代码实现环节:

   1.首先在需要拦截的页面的路由上加一个标识,meta,例如

在全局路由上添加meta:

 {path:"/index",name:'index',component:ShowBlogs,meta:{requireAuth:true}}, 

 

   2.然后在全局路由那里做下判断(一般路由router写在main.js下),如果meta为真,就进入下一个判断,登录的时候我是有将账号username存储起来,于是我根据这一点,如果username不存在,那他就是没登录,即满足meta为真&&username不存在,就让他路由跳转到登录页面

new Vue({
  el: '#app',
  },
  router:router,
  store,
  components: { App },
  template: '<App/>',
   created () {
    router.beforeEach((to, from, next) => {
    var _this = this;
    
   if(to.meta.requireAuth ){

       if(JSON.parse(localStorage.getItem("login"))==null){
          console.log('没有登录')
          _this.$router.push({path: '/',query: {redirect: to.fullPath}})
          next()
       } else {
         
          _this.$router.push({path: to.fullPath})
          next()
        }
    }
    else {
     
      next();
    }
});
    
  }
})

 

敲黑板啦   亲,注意集中力啦

首先:1)要注意this的指向,一开始用this.$router得到是unfinded,原来是this的指向有问题,所以要存储一下this的指向

              2)这样我是放在vue的created创建函数下,也可以放在外面

    3)这点是最重要的一点,先来看一下现在的逻辑:首先路由点击跳转另外一个路由的时候会先进入beforeEach这个生命函数中,然后判断这个路由是否是需要拦截的路由(根据meta),如果是就进入第二层判断,存储中是否有username,如果没有就跳到‘/’,也就是我们的登录页面,进入登录页面,又是一个新的路由,又判断登录页面是否是需要拦截的路由,否,成功跳入。登录页面那登录成功就要跳到/index这个路由,先进入beforeEach,是需要拦截的,这次有username,就路由push到index,然后要跳到index路由,又进入beforeEach,递归了,大家发现没有,一直重复跳到index路由,出不去,我也是console.log打印了1000多下,内存溢出才发现。所以我需要用一个变量来控制,如下图才是正确的操作:

 

正确的写法:

new Vue({
  el: '#app',
  data(){
    return{
      requireAuthNum:1
    }
  },
  router:router,
  store,
  components: { App },
  template: '<App/>',
   created () {
    router.beforeEach((to, from, next) => {
    var _this = this;
  // if (to.matched.some(record => record.meta.requireAuth)){  // 判断该路由是否需要登录权限
   if(to.meta.requireAuth && _this.requireAuthNum==1){

       if(JSON.parse(localStorage.getItem("login"))==null){
          console.log('没有登录')
          _this.$router.push({path: '/',query: {redirect: to.fullPath}})
          next()
       } else {
          _this.requireAuthNum++;
          _this.$router.push({path: to.fullPath})
          next()
        }
    }
    else {
      _this.requireAuthNum = 1;
      next();
    }
});
    
  }
})

 

    4)这次不只是meta为真就可以,还需要变量requireAuthNum为1才可以进入,理一下思路:点击index路由,先进入beforeEach,是需要拦截的,没有username,跳到登录页面,登录页面成功就跳到index页面,新的路由,来,先进入beforeEach,是需要拦截的且requireAuthNum刚开始为1,有username,满足条件,跳到/index路由,注意,这次requireAuthNum++,变成2,新的路由,先进入beforeEach,是需要拦截的,这时的requireAuthNum++了,不为1,跳出判断,于是就成功跳到index路由。

    5)上面的逻辑需要大家好好看一下哦,跟着本博主的思路走,边看代码边看文字的说明,还有一点小细节:就是我是index页面因为没有登录而跳到登录页面,如果登录成功应该跳到哪里,是跳到index吗,那要是我是add页面跳到登录页面,那是不是应该登录成功就跳到add页面,所以登录页面那的跳转不能写死,以前我登录成功就跳到index,如:_this.$router.push({path: '/index'});现在加上路由拦截就需要写成动态了,不知道大家有没有发现我途中的112行那的username不存在跳到登录页面,还加上query: {redirect: to.fullPath},此时的路径是/?redirect:/.......,我这里是此时的路径是/?redirect:/index,主要是存储我到底是哪个页面跳转过来的,登录页面那好做判断,login.vue判断如下:

localStorage.setItem("login",JSON.stringify(login));
            
                let redirect = decodeURIComponent(this.$route.query.redirect || '/');
              
                console.log(redirect);
                if(redirect == '/'){
                    _this.$router.push({path: '/index'});
                    console.log('login');
                }else{
                    _this.$router.push({path: redirect});
                    console.log('重定向回去')
                }
this.$route.query会自动编码,所以我需要decodeURIComponent给我解码。
redirect 判断是不是别的页面跳转过来的,此时的redirect打印出来的是/index,(携带参数就是其他页面跳过来的)这样我们就可以做判断

感谢文章:https://blog.csdn.net/Mote123/article/details/92635850
https://www.jianshu.com/p/2146341f75c6

收工,晚安!

posted @ 2019-10-25 00:49  阿泽码农  阅读(12334)  评论(1编辑  收藏  举报