vite+vue3门户网站菜单栏动态路由控制

文章讲述了如何在门户网站中通过后端接口获取并动态配置路由,包括使用`vue-router`生成菜单,以及实现路由守卫和权限控制的过程。
摘要由CSDN通过智能技术生成

   门户网站用户端需要分板块展示,板块内容由管理端配置,包括板块名称,访问路径,路由组件,展示顺序,是否展示。如下图所示:

用户访问门户网站时,展示菜单跳转通过板块配置,动态生成路由。

1.后端接口获取路由

 @GetMapping(value = "/router")
    public Result<?> getRouterList() {
        LambdaQueryWrapper<Block> query = new LambdaQueryWrapper<>();
        query.eq(Block::getIsShow, true).orderByAsc(Block::getSort);
        List<Block> blockList = blockService.list(query);
        List<Map<String, Object>> routeMapList = new ArrayList<>();
        blockList.forEach(block -> {
            Map<String, Object> map = new HashMap<>();
            map.put("path", block.getPath());
            map.put("component", block.getComponent());
            map.put("name", block.getComponent());
            routeMapList.add(map);
        });
        return Result.OK(routeMapList);
    }

2.路由配置文件  router/index.ts

import {createRouter, createWebHashHistory} from 'vue-router'

const router = createRouter({
    history: createWebHashHistory(), // hash模式:createWebHashHistory,history模式:createWebHistory
    routes: [
        {
            path: '/404',
            component: () => import('@/views/404.vue'),
            hidden: true
        },
    ]
})

export default router

3.路由守卫  router/guard/index.ts

import {Router} from 'vue-router'
import {getRouterList} from "@/api/block";
import mainStore from "../../store";

let dynamicRouters = []

export async function dynamicRouter(router: Router) {
    const {data: res} = await getRouterList()
    dynamicRouters = res.result
    const routeList = transformObjToRoute(dynamicRouters)
    routeList.forEach((route: any) => {
        //添加路由
        router.addRoute(route);
    });
}

/**
 * views目录下找页面,设置component
 * @param routeList
 */
function transformObjToRoute(routeList: any) {
    let dynamicViewsModules: any = import.meta.glob('../../views/**/*.{vue,tsx}');
    routeList.forEach((route: any) => {
        const component = route.component as string;
        if (component) {
            route.component = dynamicImport(dynamicViewsModules, component)
        }
    });
    return routeList;
}

function dynamicImport(dynamicViewsModules: any, component: string) {
    const keys = Object.keys(dynamicViewsModules);
    const matchKeys = keys.filter((key) => {
        const k = key.replace('../../views', '');
        const startFlag = component.startsWith('/');
        const endFlag = component.endsWith('.vue') || component.endsWith('.tsx');
        const startIndex = startFlag ? 0 : 1;
        const lastIndex = endFlag ? k.length : k.lastIndexOf('.');
        return k.substring(startIndex, lastIndex) === component;
    });
    if (matchKeys?.length === 1) {
        const matchKey = matchKeys[0];
        return dynamicViewsModules[matchKey];
    } else if (matchKeys?.length > 1) {
        return;
    }
}

/**
 * 页面未找到
 */
export const PAGE_NOT_FOUND_ROUTE: any = {
    path: '/:path(.*)*',
    name: "NotFound",
    component: () => import('@/views/404.vue')
};

/**
 * 动态路由权限控制
 * @param router
 */
export function setupPermissionGuard(router: Router) {
    router.beforeEach(async (to, from, next) => {
        //判断是否已经添加过动态路由,添加过,直接放行
        if (mainStore.getters.getIsDynamicAddedRoute) {
            next();
            return;
        }

        //没有添加过,添加,添加后跳转页面
        await dynamicRouter(router)
        router.addRoute(PAGE_NOT_FOUND_ROUTE);

        mainStore.commit('setDynamicAddedRoute', {
            isDynamicAddedRoute: true
        })
        next({...to, replace: true})
    });
}

4.main.ts配置路由守卫

import App from './App.vue'
import router from '@/router'
import {setupPermissionGuard} from '@/router/guard'

async function bootstrap() {
    // 创建应用实例
    const app = createApp(App);
    app.use(router) // 引用路由实例

    setupPermissionGuard(router);

    await router.isReady();

    // 挂载应用
    app.mount('#app', true);
}

bootstrap()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值