Vue3动态路由以及必坑指南

编程达人挑战赛·第5期 10w+人浏览 393人参与

概述

在现代Web应用开发中,基于角色的访问控制(RBAC)是保障系统安全的重要机制。通过动态路由技术,我们可以实现精细化的权限管理。

核心优势

1. 个性化用户体验

根据用户角色展示相应的功能菜单
隐藏无权限访问的功能模块
提供定制化的操作界面

2. 安全性增强

防止未授权用户访问敏感页面
实现细粒度的权限控制
支持令牌过期自动登出机制

3. 灵活性提升

运行时动态调整路由配置
支持多层级嵌套路由结构
便于后续权限策略扩展

完整代码:

const modules = import.meta.glob('../views/**/*.vue');

export const componentLoad = (componentPath: string) => {
    // 格式化路径:去除开头的斜杠,确保格式一致
    const formattedPath = componentPath
        .replace(/^\/?/, '')
        .replace(/\/index$/, ''); // 移除结尾的 index

    const matchPath = `../views/${formattedPath}.vue`;
    const matchPathWithIndex = `../views/${formattedPath}/index.vue`;

    if (modules[matchPath]) {
        return modules[matchPath];
    } else if (modules[matchPathWithIndex]) {
        return modules[matchPathWithIndex];
    }
    console.log(`没有找到组件: ${componentPath},联系开发人员开发!`);
    return () => import('@/views/login.vue');
};

------上面是动态加载组件的------

iimport type { Router } from "vue-router";
import NProgress from "nprogress";
import { ElMessage } from 'element-plus';
import { componentLoad } from "@/fifter/ComponentLoad.ts"
import { useAuthStore } from "@/stores/Auth.ts";
import { storeToRefs } from "pinia";
import { getCache , removeCache } from "@/utils/Cache.ts";


NProgress.configure({ showSpinner: false });

let isRefreshed = 0;

export async function initDynamicsRouter(router: Router, authRouter: any) {
    authRouter.forEach((item : any) => {
        router.addRoute({
            path: `/${item.path}`,
            name: item.name,
            meta: { isDynamic: true , component: `../${item.component}.vue` },
            component: componentLoad(item.component),
            children: item.children?.map((child: any) => {
                return {
                    path: child.path,
                    name: child.name,
                    meta: { isDynamic: true , component: `../views/${child.component}.vue` },
                    component: componentLoad(child.component)
                }
            }) || []
        });
    })
    router.addRoute({
        path: '/:catchAll(.*)',
        redirect: '/404'
    });
}


export function Safe(router: Router) {
    console.log('Safe Working...');
    router.beforeEach(async (to, from, next) => {
        console.log('路径:', to.path);
        isRefreshed++;
        NProgress.start();
        const authStore = useAuthStore();
        const { useRouters , userInfo } = storeToRefs(authStore);
        let certificate: any = getCache('certificate');
        if (certificate) {
            certificate = JSON.parse(certificate);
            console.log('过期验证:',certificate.expiredTime > new Date().getTime());
            if (certificate.expiredTime > new Date().getTime()) {
                if(!userInfo.value) {
                    console.log('获取基本信息');
                    authStore.getInfoed().then( async () =>{
                        authStore.getRouters().then(async () => {
                            await initDynamicsRouter(router, useRouters.value);
                            next({ ...to, replace: true });
                        });
                    });
                }
                if (isRefreshed === 1) {
                    await initDynamicsRouter(router, useRouters.value);
                    next({ ...to, replace: true });
                } else {
                    next();
                }
            } else {
                removeCache('certificate');
                ElMessage.warning('亲爱的用户, 您的登录已过期, 请重新登录!');
                next('/login');
            }
        } else {
            if (to.meta.auth) {
                ElMessage.warning('亲爱的用户, 请先登录!');
                next('/login');
            } else {
                next();
            }
        }
    });

    router.afterEach(() => {
        NProgress.done();
    })
}

提示:这里有一个需要注意的点是刷新页面路由丢失的问题,刷新重新加载,我们就可以加一个标识,如果没有刷新的情况会一个直增,一但刷新就会为0加1进行重新初始化动态路由!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值