动态菜单的话应该有两种思路吧,第一种是后台返回一个必须满足前台解析规则的菜单对象实体,第二种是前台拿到后台的菜单对象后(这个菜单对象不需要完全和前台匹配)取出其中的菜单名字,然后和前台写死的菜单进行比对,有相同的就显示不然隐藏。
这里介绍第二种:
首先,菜单是根据当前用户进行实时响应的,所以我需要在登录的时候进行菜单信息注入:

        /* 1.通过当前用户拿到其对应的角色 */
        /* 因为employee与role的关系是维护在中间表的,所以不能通过e.getRoles()获取 */
        List<Role> roles = employeeService.queryRolesByEmployeeSn(e.getSn());
        /* 2.通过角色拿到对应的权限 */
        List<Permission> permissions = new ArrayList<>();
        for (Role role : roles) {
            List<Permission> permissionList = permissionService.selectPermissionByRoleSn(role.getSn());
            for (Permission permission : permissionList) {
                permissions.add(permission);
            }
        }
        /* 3.通过权限拿到对应的菜单 */
        List<SystemMenu> menus = systemMenuService.getMenusByPermission(permissions);
        /* 4.让前端页面可以拿到这个菜单列表 */
        e.setSystemMenus(menus);
        created() {
            /* 存储每个用户对应的菜单 */
            /* 直接拿到的是一个字符串需要先转换成json格式 */
            let user = JSON.parse(sessionStorage.getItem('user'));
            let currentUserMenus = user.systemMenus;
            this.currentUserMenusName = [];
            for (let currentUserMenu of currentUserMenus) {
                this.currentUserMenusName.push(currentUserMenu.name);
            }
            /* 根据获取的systemMenus动态修改菜单 */
            /* 将菜单动态修改放到created中 */
            this.dynamicChangeMenu();
        },

前端处理好菜单信息后进行显示:

        methods: {
            /* 动态修改菜单 */
            dynamicChangeMenu() {
                for (let item of this.items) {
                    /* 系统首页不算在动态菜单的计算范围内 */
                    item.hidden = this.currentUserMenusName.indexOf(item.title) === -1 && item.title !== '系统首页';
                    /* 如果有子集 */
                    if (item.subs) {
                        for (let subItem of item.subs) {
                            /* 当当前集合不匹配或者父集合不匹配时 */
                            subItem.hidden = this.currentUserMenusName.indexOf(subItem.title) === -1 || item.hidden;
                        }
                    }
                }
            }
        },

根据这个hidden属性决定是否显示当前节点
后面的工作就是遍历菜单并显示了,看你的前端代码怎么写了:

<template v-for="item in items">
                <!-- 如果有子级 -->
                <template v-if="item.subs&&item.hidden===false">
                    <el-submenu :index="item.index" :key="item.index">
                        <template slot="title">
                            <i :class="item.icon"></i>
                            <span slot="title">{{ item.title }}</span>
                        </template>
                        <template v-for="subItem in item.subs">
                            <el-menu-item
                                    v-if="subItem.hidden===false"
                                    :index="subItem.index"
                                    :key="subItem.index">
                                <template slot="title">{{ subItem.title }}</template>
                            </el-menu-item>
                        </template>
                    </el-submenu>
                </template>
                <!-- 如果没有子集 -->
                <!-- 这里显示的是系统首页,因为它没有子集 -->
                <template v-else-if="!item.subs">
                    <el-menu-item :index="item.index" :key="item.index">
                        <i :class="item.icon"></i>
                        <span slot="title">{{ item.title }}</span>
                    </el-menu-item>
                </template>
            </template>

完成

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐