私活必备,一个react+vite+antd的标准后台管理系统开发模版,动态菜单配置、权限精确到按钮

先看几张图:



在现代前端开发中,构建一个高效灵活的后台管理系统已成为许多开发者的一个基本要求,发布构建是否够快,尤其是当项目不断迭代,代码不断增多后,是否还能高效构建。

本文将介绍一个基于React、Vite和Antd的标准后台管理系统开发模板,支持动态菜单配置和权限精确到按钮的实现。通过这个模板,开发者可以迅速搭建起一个功能完备、可扩展性强的后台管理系统,没有使用create-rect-app脚手架,完全从0开始自己搭建,使用了目前比较先进的技术。





技术栈:

react+redux+hook+vite+antd+less+axios  基于vite构建,本地开发体验很不错

非服务端渲染,仿antd-pro外观,但没有使用dva和roadhog

目录结构:

项目启动

pnpm install       // 安装依赖模块
pnpm run dev       // 运行开发环境
pnpm run build     // 正式打包,生成最终代码
pnpm run preview   // 本地运行正式打包后的最终代码
pnpm run prettier  // 一键格式化代码


启动问题:

执行 npm run build 后有提示ts错误,传入的类型和实际定义的不符


解决办法:找到getData方法的定义,入参增加any即可。


本地开发走mock:

本地使用 mockjs 进行接口拦截做本地mock数据。

正式环境需要关闭此配置。


/**
 * MOCK模拟数据
 * 不需要下面这些mock配置,仅本地用
 * */
import Mock from "mockjs";
// @ts-ignore
import mock from "../../mock/app-data.js";
Mock.mock(/\/api.*/, (options: any) => {
  const res = mock(options);
  return res;
});



动态菜单配置:

接口按照此格式返回即可。

/**
 * MOCK模拟数据
 * 不需要下面这些mock配置,仅本地用
 * 正式打包需要去掉
 * */
import Mock from "mockjs";
// @ts-ignore
import mock from "../../mock/app-data.js";
Mock.mock(/\/api.*/, (options: any) => {
  const res = mock(options);
  return res;
});// 所有的菜单数据
const menus = [
  {
    id: 1,
    title: "首页",
    icon: "icon-home",
    url: "/home",
    parent: null,
    desc: "首页",
    sorts: 0,
    conditions: 1,
  },
  {
    id: 2,
    title: "系统管理",
    icon: "icon-setting",
    url: "/system",
    parent: null,
    desc: "系统管理目录分支",
    sorts: 1,
    conditions: 1,
  },
  {
    id: 3,
    title: "用户管理",
    icon: "icon-user",
    url: "/system/useradmin",
    parent: 2,
    desc: "系统管理/用户管理",
    sorts: 0,
    conditions: 1,
  },
  {
    id: 4,
    title: "角色管理",
    icon: "icon-team",
    url: "/system/roleadmin",
    parent: 2,
    desc: "系统管理/角色管理",
    sorts: 1,
    conditions: 1,
  },
  {
    id: 5,
    title: "权限管理",
    icon: "icon-safetycertificate",
    url: "/system/poweradmin",
    parent: 2,
    desc: "系统管理/权限管理",
    sorts: 2,
    conditions: 1,
  },
  {
    id: 6,
    title: "菜单管理",
    icon: "icon-appstore",
    url: "/system/menuadmin",
    parent: 2,
    desc: "系统管理/菜单管理",
    sorts: 3,
    conditions: 1,
  },
];// 所有的菜单数据
const menus = [
  {
    id: 1,
    title: "首页",
    icon: "icon-home",
    url: "/home",
    parent: null,
    desc: "首页",
    sorts: 0,
    conditions: 1,
  },
  {
    id: 2,
    title: "系统管理",
    icon: "icon-setting",
    url: "/system",
    parent: null,
    desc: "系统管理目录分支",
    sorts: 1,
    conditions: 1,
  },
  {
    id: 3,
    title: "用户管理",
    icon: "icon-user",
    url: "/system/useradmin",
    parent: 2,
    desc: "系统管理/用户管理",
    sorts: 0,
    conditions: 1,
  },
  {
    id: 4,
    title: "角色管理",
    icon: "icon-team",
    url: "/system/roleadmin",
    parent: 2,
    desc: "系统管理/角色管理",
    sorts: 1,
    conditions: 1,
  },
  {
    id: 5,
    title: "权限管理",
    icon: "icon-safetycertificate",
    url: "/system/poweradmin",
    parent: 2,
    desc: "系统管理/权限管理",
    sorts: 2,
    conditions: 1,
  },
  {
    id: 6,
    title: "菜单管理",
    icon: "icon-appstore",
    url: "/system/menuadmin",
    parent: 2,
    desc: "系统管理/菜单管理",
    sorts: 3,
    conditions: 1,
  },
];


登录信息保存:

登录状态保存在的localstorage内

 // 用户提交登录
  const onSubmit = async (): Promise<void> => {
    try {
      const values = await form.validateFields();
      setLoading(true);
      const res = await loginIn(values.username, values.password);
      if (res && res.status === 200) {
        message.success("登录成功");
        if (rememberPassword) {
          localStorage.setItem(
            "userLoginInfo",
            JSON.stringify({
              username: values.username,
              password: tools.compile(values.password), // 密码简单加密一下再存到localStorage
            })
          ); // 保存用户名和密码
        } else {
          localStorage.removeItem("userLoginInfo");
        }
        /** 将这些信息加密后存入sessionStorage,并存入store **/
        sessionStorage.setItem(
          "userinfo",
          tools.compile(JSON.stringify(res.data))
        );
        await dispatch.app.setUserInfo(res.data);
        navigate("/"); // 跳转到主页
      } else {
        message.error(res?.message ?? "登录失败");
        setLoading(false);
      }
    } catch (e) {
      // 验证未通过
    }
  };


github地址:https://github.com/javaLuo/react-admin

相关推荐

  • 老外整了个领先的幻觉检测模型Lynx
  • 孟晚舟:不要选择和机器竞争的职业,萝卜无人车会是特洛伊木马吗?
  • 复旦教授:当初脑子一定被驴踢了,不然怎么会上这帮龟孙子的当
  • 成都周报 | 174亿最大重组案获批,首批未来产业天使子基金签约
  • 一家半导体研发商融了三个亿丨投融周报
  • 这几个Python效率工具非常好用~
  • 枪手射8发子弹!观众1死2伤!特朗普遭枪击事件细节披露
  • 聊一聊ES2024有啥新特性
  • 【文末赠书】大模型时代,如何用时间序列与机器学习解锁未来?
  • 招聘|Anytime AI-全栈开发工程师
  • 金融场景中的指标体系建设与应用
  • 7B最强长视频模型! LongVA视频理解超千帧,霸榜多个榜单
  • Meta开发System 2蒸馏技术,Llama 2对话模型任务准确率接近100%
  • 数据匮乏仍是通用具身智能面前的高墙吗?
  • 非法阻止员工披露AI安全风险,OpenAI严厉「封口协议」再遭举报
  • 直击真实的甲方AGI需求,人工智能赋能产业融通发展论坛顺利召开
  • AI大模型有望再扩1000倍!剑桥耶鲁康奈尔:PNN是变革关键
  • AI机器人伴侣成美国老年人新宠!美国每年花70万刀,失去爱人的84岁老人重新笑了
  • 设计师+AI,3个月就能完成一套千字中文字库@智琮科技
  • 明年,每个人都能零基础创作3D内容 | 对话VAST宋亚宸