最近做项目,遇到了动态路由权限问题,看了一些文章,踩了两天坑,算是实现了。和大家分享一下,有错误的地方请大神指出来。目前没有接口,我采用的vuex存储用户名信息来获取配置的路由js。

1、先看一下我的路由目录,如下:

1.1、_import_development.js;这个是开发环境引入组件的方式,代码如下:

      这里的路径按照自己的代码存放获取。(我的组件存放是按照路由分的文件夹,自我感觉非常清晰

module.exports = file => require('@/pages/components/' + file + '/index.vue').default;

1.2、_import_production.js;这个是生产环境引入组件的方式,代码如下:

module.exports = file => () => import ('@/pages/components/' + file + '/index.vue');

1.2、index.js;这个是路由主js,代码如下:

import Vue from 'vue'
import Router from 'vue-router'
import staticRouter from './staticRouter'//静态路由
Vue.use(Router)

const originalPush = Router.prototype.push;
Router.prototype.push = function push(location) {
    return originalPush.call(this, location).catch(err => err)
};
const router = new Router({
    routes: staticRouter
});
export default router;

1.4、resetRouter.js;这个重置路由,用于切换用户后重置路由,代码如下:使用方法:在系统任意界面直接引入此js,在销毁周期调用此函数,可重置路由;

import Vue from 'vue'
import Router from 'vue-router'
import router from '@/router'
import staticRouter from './staticRouter'//静态路由
export function resetRouter() {
    const newRouter = new Router({
        routes: staticRouter
    });
    router.matcher = newRouter.matcher;
}
// 重置路由
import {
    resetRouter
} from '@/router/resetRouter.js';
//销毁阶段直接使用
destroyed() {    
   resetRouter(); //退出系统,重置路由
}

1.5、staticRouter.js;静态路由存放这里不能引入404路由,否则点击完跳转直接进入404,404配置我在动态js里配置

import login from '@/components/login'; //系统架构单独引入
import serverError from '@/components/serverError'; //服务器错误
const staticRouter = [{
        "path": "/",
        "name": "login",
        "component": login
    },
    {
        "path": "/serverError",
        "name": "serverError",
        "component": serverError
    }
];
export default staticRouter;

第一阶段完毕,我的路由配置文件夹是这样的,接下来我们讲解如何引用这些文件。

2、路由需要在两个js中引入:

    2.1、main.js引入,这个我就不讲了。大家都会。

    2.2 、动态路由js,这里我会细讲一下如何使用,我的命名:getRouter.js,写在配置文件夹下边,如下:

          2.2.1、引入文件

import router from '@/router';//路由
import axios from 'axios';//axios请求,
import store from '@/store';//vuex
import NProgress from 'nprogress';//页面加载进度条
//获取组件的方法,一种开发环境,一种生产环境
const _import = require('@/router/_import_' + process.env.NODE_ENV);
import system from '@/pages'; //系统架构单独引入
import pageError from '@/components/pageError'; //路由错误 404
let systemRouter; //系统菜单,这里要提前声明,否则直接添加没有判断,会进入死循环

          2.2.2、获取路由,在路由前置守卫获取

router.beforeEach(async(to, from, next) => {
    // 判断路由是否去登录界面
    NProgress.start();//路由动画,自己直接装npm 就可以
    if (to.name === 'login') {//如果进入登录页面,我们直接进行路由连接
        systemRouter = undefined;//先清空系统路由变量
        next();
    } else {
        // 判断是否已经登录
        const islogin = JSON.parse(window.sessionStorage.getItem("isLogin"));
        if (islogin) {
            // 获取登录信息,储存在vuex
            const userDeatilInfo = JSON.parse(window.localStorage.getItem("userDeatilInfo"));
            store.dispatch('userInfo/setUserInfo', userDeatilInfo);
            //判断是否有系统路由
            judgeHasSystem(to, next)
        } else {
            // 未登录跳转至登陆页
            next({
                path: './'
            });
        }
    };
});
//路由后置钩子,路由结束动画
router.afterEach(() => {
    NProgress.done()
});
// 判断是否有系统页码
function judgeHasSystem(to, next) {
    // 如果有则直接跳转,这里就需要用到声明的系统路由
    if (systemRouter) {
        next();
    } else {
        // 直接进行请求获取新的菜单
        // 404界面在动态路由配置,否则无法进行登录导航
        let systemRouterStr = [{
            "path": "*",
            "name": "pageError",
            "component": 'pageError'
        }];
        // 如果本地没有系统路由缓存则进行异步获取
        //我这里使用的是本地配置文件,如果真是后台,下边部分大家可以修改成axios方式,可以用
        // async await;或者直接在.then之后进行操作,
        const username = store.state.userInfo.useInfo.username;
        if (configRouter[username]) {
            systemRouterStr.push(configRouter[username][0])
        } else {
            systemRouterStr.push(configRouter.other[0])
        };
        systemRouter = systemRouterStr;
        routerNext(to, next);//执行跳转
    }
}
// 执行跳转
function routerNext(to, next) {
    const realRouter = filterAxiosRouter(systemRouter) //过滤路由
    router.addRoutes(realRouter) //动态添加路由
        // 执行跳转
    next({
        ...to,
        replace: true
    });
};
// 加载组件过滤路由
function filterAxiosRouter(asyncRouterMap) { //遍历后台传来的路由字符串,转换为组件对象
    const accessedRouters = asyncRouterMap.filter(route => {
        if (typeof(route.component) === 'string') {
            if (route.component) {
                switch (route.component) {
                    case 'system':
                        route.component = system;
                        break;
                    case 'pageError':
                        route.component = pageError;
                        break;
                    default:
                        // router里已经声明了获取组件的方式,回顾两种环境下的引入组件方式
                        route.component = _import(route.component);
                        break;
                };
            };
        }
        //判断是否有子路由
        if (route.children && route.children.length) {
            route.children = filterAxiosRouter(route.children);
        };
        return true
    });
    return accessedRouters
};

           2.2.3、将获取路由的js,在main.js种引入

import '@/utils/getRouter.js'; //获取路由

个人配置的路由静态文件,仅供参考

const configRouter = {
    //管理员路由
    admin: [{
        "path": "/system",
        "name": "system",
        "component": "system",
        "children": [{
            "path": "",
            "name": "1",
            "component": "1",
            "meta": {
                "title": "1"
            }
        }, {
            "path": "2",
            "name": "2",
            "component": "2",
            "meta": {
                "title": "2"
            }
        }, {
            "path": "3",
            "name": "4",
            "component": "4",
            "meta": {
                "title": "3"
            }
        }, {
            "path": "4",
            "name": "4",
            "component": "4",
            "meta": {
                "title": "4"
            }
        }, {
            "path": "5",
            "name": "5",
            "component": "5",
            "meta": {
                "title": "5"
            }
        }]
    }],
    // 其他路由
    other: [{
        "path": "/system",
        "name": "system",
        "component": "system",
        "children": [{
            "path": "",
            "name": "2",
            "component": "2",
            "meta": {
                "title": "2"
            }
        }, {
            "path": "3",
            "name": "3",
            "component": "3",
            "meta": {
                "title": "3"
            }
        }]
    }, ]
}

至此,我的动态路由是这样配置的,如果有缺陷,请大神指导指导,谢谢。

 

Logo

前往低代码交流专区

更多推荐