vue-pure-admin菜单配置详解:动态菜单生成与权限关联

vue-pure-admin菜单配置详解:动态菜单生成与权限关联

【免费下载链接】vue-pure-admin 全面ESM+Vue3+Vite+Element-Plus+TypeScript编写的一款后台管理系统(兼容移动端) 【免费下载链接】vue-pure-admin 项目地址: https://gitcode.com/GitHub_Trending/vu/vue-pure-admin

引言

在现代后台管理系统中,菜单配置是核心功能之一。vue-pure-admin作为一款基于Vue3+TypeScript+Element Plus的开源后台管理系统,提供了强大而灵活的菜单配置机制。本文将深入解析vue-pure-admin的菜单系统,重点介绍动态菜单生成和权限关联的实现原理。

菜单系统架构概览

vue-pure-admin的菜单系统采用分层架构设计,主要包含以下几个核心模块:

mermaid

路由配置详解

静态路由配置

静态路由在src/router/modules/目录下定义,系统会自动导入所有模块文件:

// 自动导入所有静态路由模块
const modules: Record<string, any> = import.meta.glob(
  ["./modules/**/*.ts", "!./modules/**/remaining.ts"],
  { eager: true }
);

动态路由配置

动态路由通过API接口从后端获取,配置在mock/asyncRoutes.ts中:

export default defineFakeRoute([
  {
    url: "/get-async-routes",
    method: "get",
    response: () => {
      return {
        success: true,
        data: [
          systemManagementRouter,
          systemMonitorRouter,
          // ...其他路由
        ]
      };
    }
  }
]);

菜单数据结构

vue-pure-admin的菜单数据采用标准的路由配置格式,每个菜单项包含以下关键属性:

属性类型说明示例
pathstring路由路径/system/user
namestring路由名称SystemUser
componentstring/Component组件路径或组件system/user/index
metaobject元数据配置{ title: '用户管理', icon: 'user' }
childrenarray子菜单数组[{ path: '/user/list', ... }]

meta配置详解

meta对象是菜单配置的核心,支持丰富的配置选项:

{
  path: "/system/user",
  name: "SystemUser",
  meta: {
    title: "用户管理",           // 菜单显示名称
    icon: "ri:user-line",       // 菜单图标
    roles: ["admin", "editor"], // 访问权限角色
    showLink: true,            // 是否显示在菜单中
    keepAlive: false,          // 是否缓存页面
    rank: 10,                  // 菜单排序权重
    auths: ["user:add", "user:edit"] // 按钮级别权限
  }
}

动态菜单生成机制

1. 路由初始化流程

mermaid

2. 权限过滤实现

系统通过filterNoPermissionTree函数实现基于角色的菜单过滤:

function filterNoPermissionTree(data: RouteComponent[]) {
  const currentRoles = storageLocal().getItem<DataInfo<number>>(userKey)?.roles ?? [];
  const newTree = cloneDeep(data).filter((v: any) =>
    isOneOfArray(v.meta?.roles, currentRoles)
  );
  newTree.forEach(
    (v: any) => v.children && (v.children = filterNoPermissionTree(v.children))
  );
  return filterChildrenTree(newTree);
}

3. 菜单组装过程

在权限存储模块中完成菜单的最终组装:

// src/store/modules/permission.ts
handleWholeMenus(routes: any[]) {
  this.wholeMenus = filterNoPermissionTree(
    filterTree(ascending(this.constantMenus.concat(routes)))
  );
  this.flatteningRoutes = formatFlatteningRoutes(
    this.constantMenus.concat(routes) as any
  );
}

多级菜单处理

层级结构规范化

vue-pure-admin支持无限层级的菜单结构,但为了性能优化,系统会将三级及以上路由拍平为二级:

function formatTwoStageRoutes(routesList: RouteRecordRaw[]) {
  if (routesList.length === 0) return routesList;
  const newRoutesList: RouteRecordRaw[] = [];
  routesList.forEach((v: RouteRecordRaw) => {
    if (v.path === "/") {
      newRoutesList.push({
        component: v.component,
        name: v.name,
        path: v.path,
        redirect: v.redirect,
        meta: v.meta,
        children: []
      });
    } else {
      newRoutesList[0]?.children.push({ ...v });
    }
  });
  return newRoutesList;
}

菜单排序机制

系统通过meta.rank属性控制菜单显示顺序:

function ascending(arr: any[]) {
  arr.forEach((v, index) => {
    if (handRank(v)) v.meta.rank = index + 2;
  });
  return arr.sort(
    (a: { meta: { rank: number } }, b: { meta: { rank: number } }) => {
      return a?.meta.rank - b?.meta.rank;
    }
  );
}

权限关联实现

1. 角色级别权限

在路由配置中通过roles字段定义菜单访问权限:

{
  path: "/system/user",
  meta: {
    roles: ["admin"]  // 只有admin角色可以访问
  }
}

2. 按钮级别权限

通过auths字段实现更细粒度的权限控制:

{
  path: "/permission/button/router",
  meta: {
    auths: [
      "permission:btn:add",
      "permission:btn:edit", 
      "permission:btn:delete"
    ]
  }
}

3. 权限验证工具函数

系统提供了一系列权限验证工具函数:

// 检查按钮权限
function hasAuth(value: string | Array<string>): boolean {
  const metaAuths = getAuths();
  if (!metaAuths) return false;
  const isAuths = isString(value)
    ? metaAuths.includes(value)
    : isIncludeAllChildren(value, metaAuths);
  return isAuths ? true : false;
}

实战配置示例

示例1:系统管理菜单配置

const systemManagementRouter = {
  path: "/system",
  meta: {
    icon: "ri:settings-3-line",
    title: "系统管理",
    rank: 10
  },
  children: [
    {
      path: "/system/user/index",
      name: "SystemUser",
      meta: {
        icon: "ri:admin-line",
        title: "用户管理",
        roles: ["admin"]
      }
    },
    {
      path: "/system/role/index",
      name: "SystemRole",
      meta: {
        icon: "ri:admin-fill",
        title: "角色管理",
        roles: ["admin"]
      }
    }
  ]
};

示例2:带权限按钮的菜单配置

const permissionRouter = {
  path: "/permission/button",
  meta: {
    title: "按钮权限",
    icon: "ep:lollipop"
  },
  children: [
    {
      path: "/permission/button/router",
      name: "PermissionButtonRouter",
      meta: {
        title: "路由按钮权限",
        auths: ["btn:add", "btn:edit", "btn:delete"]
      }
    }
  ]
};

高级特性

1. 外链菜单配置

支持配置外部链接菜单项:

{
  path: "/external",
  name: "https://pure-admin.cn/",
  meta: {
    title: "外部链接",
    roles: ["admin", "common"]
  }
}

2. iframe嵌入菜单

支持通过iframe嵌入外部页面:

{
  path: "/iframe/vue3",
  name: "FrameVue",
  meta: {
    title: "Vue3文档",
    frameSrc: "https://cn.vuejs.org/",
    keepAlive: true
  }
}

3. 隐藏菜单配置

通过showLink: false配置不在菜单中显示的路由:

{
  path: "/tabs/query-detail",
  meta: {
    showLink: false,  // 不在菜单中显示
    activePath: "/tabs/index"
  }
}

常见问题与解决方案

问题1:菜单不显示或显示异常

解决方案:

  • 检查meta.showLink配置是否为true
  • 确认用户角色是否具有访问权限
  • 验证路由路径配置是否正确

问题2:权限控制失效

解决方案:

  • 检查roles数组配置是否正确
  • 确认用户登录后角色信息是否正确存储
  • 验证权限过滤函数是否正常工作

问题3:菜单排序混乱

解决方案:

  • 为每个菜单项配置合适的rank
  • 确保排序函数正常工作

最佳实践建议

  1. 菜单分层设计:合理规划菜单层级,建议不超过三级
  2. 权限最小化:遵循最小权限原则,精确控制每个菜单的访问权限
  3. 图标规范化:使用统一的图标库,保持界面风格一致
  4. 路由命名规范:采用有意义的命名约定,便于维护和理解
  5. 性能优化:合理使用keepAlive缓存常用页面

总结

vue-pure-admin的菜单配置系统提供了强大而灵活的解决方案,通过结合静态路由和动态路由,实现了完整的权限控制体系。本文详细介绍了菜单配置的各个方面,包括数据结构、权限关联、动态生成机制等,希望能够帮助开发者更好地理解和使用vue-pure-admin的菜单系统。

通过合理的菜单配置和权限管理,可以构建出既安全又易用的后台管理系统,满足各种复杂的业务需求。

【免费下载链接】vue-pure-admin 全面ESM+Vue3+Vite+Element-Plus+TypeScript编写的一款后台管理系统(兼容移动端) 【免费下载链接】vue-pure-admin 项目地址: https://gitcode.com/GitHub_Trending/vu/vue-pure-admin

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值