解决微前端侧边栏的差异

375 阅读2分钟

微前端侧边栏配置

背景:

image.png 侧边栏在基架中

由于业务需求,侧边栏总共有三种情况

1.项目列表页的侧边栏

2.项目详情页的侧边栏

3.用户侧的侧边栏

4.有些页面不需要菜单栏

第一种:

image.png

第二种:

image.png

第三种:

image.png

业务刚开始的时候,都是菜单栏都是固定写死的,然后根据路由来判断显示三个中的哪一个,判断逻辑比较复杂。

问题:

1.随着业务的需求不断发展,菜单越来越多。

2.有些菜单在详情页和用户侧都显示。

3.菜单还涉及相关权限变化。

解决方案:

我们首先想到的就是做配置化了,直接有系统下发。

问题来了,我们该怎么配置。

方案一: 传统的管理系统,都是前端有一颗完整的路由树,后端接口下发对应的权限路由id,前端拿到有权限的路由id,再去遍历整颗树,获得一颗新的权限树,我们也可以这样去做,但是你每次新增一个菜单,必须修改基架。

方案二: 所有的菜单都是有接口下发,在基架进行重组成菜单,这样每次修改【基架都是无感的】 单一菜单数据结构:

    {
        "label": "应用", // 菜单名称
        "id": "sub-app", // id 每个菜单的id 唯一性
        "parentId": "", // 父id 菜单的上一级,如果没有就是一级菜单
        "sandbox": true, // 是否测试环境
        "barType": "normal", // 列表页侧边栏 详情页 用户侧 或者无
        "online": true, // 是否线上环境
        "microName": "user-frontend", // 代表页面内容来自哪个系统
        "to": "/idaas/app" // 跳转路径
    }

形成菜单树:

// menulist是单个菜单的数组
 menuList.forEach(item => {
        if (!listBarMap[item.barType]) {
            listBarMap[item.barType] = [];
        }
        listBarMap[item.barType].push(item);
    });
    Object.keys(listBarMap).forEach((key: BarType) => { 
        const oneLevelMenu = listBarMap[key].filter(item => !item.parentId);
        const twoLevelMenu = listBarMap[key].filter(item => item.parentId);
        twoLevelMenu.forEach(item => {
            const parent = oneLevelMenu.find(oneItem => oneItem.id === item.parentId);
            if (parent) {
                parent.children = parent.children || [];
                parent.children.push(item);
            }
        });
        menuMap[key] = oneLevelMenu;
    });

处理后的数据结构如图:

image.png

这样通过菜单可以直接遍历

方案选择:

综合考略选择了方案二,这样自系统新增页面的时候,不需要再次修改基架系统了。

结果:

目前看已经完全满足业务需求的变化,如果有更好的解决方案欢迎一起讨论