vue 配置路由 + 用户权限生成动态路由 踩过的那些坑

整个动态路由的设置是我自己研究写的,现在项目中没发现什么问题。如发现有问题,欢迎前来纠正,谢谢!!!

链接:https://pan.baidu.com/s/1J9R2TkqJk0H9JMjqp2WcFw 
提取码:n4rk 
复制这段内容后打开百度网盘手机App,操作更方便哦


此包因为涉及后台交互未写成mock形式,下载后不可本地运行。node_modules需要自己本地安装。

可以参考项目中相关页面的设置

功能讲解如下:

cnpm install vue-router --save

注意参数--save

  --save 可以理解成生产环境,会把依赖包名称添加到 package.json 文件 dependencies 键下,dependencies是运行时依赖。

  --save-dev 则是开发环境, 添加到 package.json 文件 devDependencies 键下,devDependencies是开发时的依赖,如生产时不需要用到压缩库应该安装到devDependencies 。

动态路由

相关网址:例1  https://blog.csdn.net/s8460049/article/details/61190709

                  例2   http://www.jb51.net/article/123774.htm  (脚本之家)

                  例3   https://segmentfault.com/a/1190000009506097  (根据权限设置路由)

 

具体实现

  1. 创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。

  2. 当用户登录后,获取用role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。

  3. 调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。

  4. 使用vuex管理路由表,根据vuex中可访问的路由渲染侧边栏组件。

小建议:这里还有一个小hack的地方,就是router.addRoutes之后的next()可能会失效,因为可能next()的时候路由并没有完全add完成,好在查阅文档发现

next('/') or next({ path: '/' }): redirect to a different location. The current navigation will be aborted and a new one will be started.

根据权限生成动态路由步骤:

1.路由配置

main.js

  

router: router.js  index.js

 

2.登录成功  因路由还是默认路由,页面跳转到404,解决方法如下:

login.js  动态添加路由

 

3.页面刷新  页面跳转到404,解决方法如下:

这是因为刷新会导致Vue重新实例化,路由也恢复到了初始路由,于是当前路径又被重定向到了404,

这个问题的根源是可用路由没有实现持久化,

那么可以通过将路由数据存sessionStorage来解决,实例化之前如果检测到本地路由就直接合并路由

 

解决办法:初始路由删除404配置,动态添加

router.js

main.js

 

4.菜单栏始终未空  未能加载路由

1.addroute已经成功了,所以可以跳转到新增的路由页。

2. addroute只是在路由里加了新的路由,也就是你可以通过url跳转,并不是个你添加新的菜单,加新的菜单还需要你自己根据权限判断,写代码处理

3.渲染menu不应该遍历路由去生成,因为addroutes后,路由虽然增加了,但路由不是响应数据(未观察,且未订阅),是不会对你的视图触发变化的。

解决办法:指令    Vue.directive

建议解决方案:使用vuex,对路由信息进行状态管理,把初始的路由数据存到store里,menu依靠store进行渲染及更新,addroutes后再把新增路由push进store存储的路由数组中,即可以触发menu更新。

----------------------------------------------------------------------------------------------------------------------

实际步骤:

①store module : permission.js

 action:GenerateRoutes   根据角色生成动态路由

import { constRouters, appRouterAdmain, appRouterManger, appRouterYyb } from '../../routes/routes'
/**

* 通过meta.role判断是否与当前用户权限匹配

* @param roles

* @param route

*/

function hasPermission(roles, route) {

  if (route.meta && route.meta.roles) {

    return roles.some(role => route.meta.roles.indexOf(role) >= 0)

  } else {

    return true

  }

}
/**

* 递归过滤异步路由表,返回符合用户角色权限的路由表

* @param asyncRouterMap

* @param roles

*/
function filterAsyncRouter(asyncRouterMap, roles) {

      const accessedRouters = asyncRouterMap.filter(route => {

        if (hasPermission(roles, route)) {

             if (route.children && route.children.length) {

                route.children = filterAsyncRouter(route.children, roles)

              }

          return true

        }

        return false

      })

      return accessedRouters

}
const permission = {

      state: {

        routers: constRouters,

        addRouters: []

      },

      mutations: {

        SET_ROUTERS: (state, routers) => {

              state.addRouters = routers

              state.routers = constRouters.concat(routers)

        }

      },

      actions: {

        GenerateRoutes({ commit }, data) {

              return new Promise(resolve => {

                const { roles } = data

                let accessedRouters

                console.log(data)

                if (roles.indexOf('admin') >= 0) {

                      accessedRouters = appRouterAdmain

                }else if (roles.indexOf('shenhe') >= 0) {

                      accessedRouters = appRouterManger

                }else if (roles.indexOf('999') >= 0) {

                      accessedRouters = appRouterYyb

                }

                commit('SET_ROUTERS', accessedRouters);

                resolve()

              })

        }

      }

}
export default permission

 ②getter 方法

③home.vue  导入store 数据

5.router.beforEach 无限循环,页面跳转不会触发无限循环,刷新页面就会

原因:

调用next()时会直接进入to路由,不会再调用beforeEach()

而调用next('xxx')后会拦截路由使得路由重定向xxx,并再次调用beforeEach(),因此必须做好条件判断避免陷入死循环。

解决步骤:

①将所有next('xxx') --> next()  问题还是没解决。

②发现是重复添加路由造成。

Home.vue 已经调用了路由添加功能,与 router.beforeEach 添加路由重复冲突

 

 

5.静态路由正常。动态路由刷新页面不能展开当前路由  点击跳转没问题

    猜想:

    ①可能是因为路由是动态加载,动态路由在for循环之后,所以未能展开

    ②可能是vue 参数传的不对

        

 

 

解决办法:

① 固定展示某一项  :default-openeds="['1']"

   

    

    问题: 但是每次点击切换其他路由,路由刷新 固定指向第一个路由。

 

②需动态展示当前栏目

第一次进入页面/刷新页面           点击切换页面正常显示

          

 

相关动态路由设置代码:

  

6.换一种路由添加方式

home.vue 去掉动态更改路由方法

menuItem: function() {

      // 动态获取可访问路由表

      // this.$router.options.routes = this.$store.state.permission.addRouters;

      // return this.$store.state.permission.addRouters

}  

效果:

首次登录:                                           刷新页面:

    

路由由vuex获取:$router.options.routes ===>  $store.getters.addRouters

import store from "../vuex/store"

main.js 设置路由

new Vue({

    router,

       store,

       render: h => h(App),

       created: function() {

              let isLogin = util.getCookie('role');

              if(!isLogin){

                     return this.$router.push({path:'/login'});

              }

              

              //存菜单

              let userPath = '';

              if(isLogin == 20){

                     userPath = constRouters.concat(appRouterManger);

              }else if(isLogin == 50){

                      userPath = constRouters.concat(appRouterYyb);

              }else{

                      userPath = constRouters.concat(appRouterAdmain);

              }      

              //注入时拼接404处理路由

              this.$router.addRoutes(userPath.concat([{

                      path: '*',

                      redirect: '/404'

              }]));

              // 因为addroutes后,$router.options.routes不会更新,所以需要手动添加。

                          //  最后发现这句话可以不加

              this.$router.options.routes = userPath;

       },

       mounted () {

   }

}).$mount('#app')

main.js  --> router.beforeEach   用户权限路由有store分配

new Vue({
    .....
    //存菜单    
    let userPath = '';
    if(isLogin == 20){
         userPath = constRouters.concat(appRouterManger);
    }else if(isLogin == 50){
         userPath = constRouters.concat(appRouterYyb);
    }else{
         userPath = constRouters.concat(appRouterAdmain);
    }      
    //注入时拼接404处理路由
    this.$router.addRoutes(userPath.concat([{
         path: '*',
         redirect: '/404'
    }]));
})

上面的存菜单代码块替换为:

let userPath = constRouters.concat(store.getters.addRouters);
//注入时拼接404处理路由
this.$router.addRoutes(userPath.concat([{
     path: '*',
     redirect: '/404'
}]));

vuex - moudle - permission.js  设置权限路由:

登陆成功后页面为空:

解决办法:

login.vue  登录接口内部手动添加路由 :   this.$router.addRouters() 

至此动态路由功能完成,没问题!

 

 

  • 45
    点赞
  • 335
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值