UmiJS-新项目要处理的工作


布局

import { ProLayoutProps } from "@ant-design/pro-components";

/**
 * @name
 */
const Settings: ProLayoutProps & {
  pwa?: boolean;
  logo?: string;
} = {
  navTheme: "light",
  // 拂晓蓝
  colorPrimary: "#1890ff",
  layout: "mix",
  contentWidth: "Fluid",
  fixedHeader: false,
  fixSiderbar: true,
  colorWeak: false,
  title: "Ant Design Pro",
  pwa: true,
  logo: "https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg",
  iconfontUrl: "",
  token: {
    // 参见ts声明,demo 见文档,通过token 修改样式
    //https://procomponents.ant.design/components/layout#%E9%80%9A%E8%BF%87-token-%E4%BF%AE%E6%94%B9%E6%A0%B7%E5%BC%8F
  },
};

export default Settings;

文件目录

目录结构

数据来源参考 Ant Design Pro

├── config # umi 配置,包含路由,构建等配置
├── mock # 本地模拟数据
├── public
│ └── favicon.png # Favicon
├── src
│ ├── assets # 本地静态资源
│ ├── components # 业务通用组件
│ ├── e2e # 集成测试用例
│ ├── layouts # 通用布局
│ ├── models # 全局 dva model
│ ├── pages # 业务页面入口和常用模板
│ ├── services # 后台接口服务
│ ├── utils # 工具库
│ ├── locales # 国际化资源
│ ├── global.less # 全局样式
│ └── global.ts # 全局 JS
├── tests # 测试工具
├── README.md
└── package.json

页面目录结构

src
├── components
└── pages
├── Welcome // 路由组件下不应该再包含其他路由组件,基于这个约定就能清楚的区分路由组件和非路由组件了
| ├── components // 对于复杂的页面可以再自己做更深层次的组织,但建议不要超过三层
| ├── Form.tsx
| ├── index.tsx // 页面组件的代码
| └── index.less // 页面样式
├── Order // 路由组件下不应该再包含其他路由组件,基于这个约定就能清楚的区分路由组件和非路由组件了
| ├── index.tsx
| └── index.less
├── user // 一系列页面推荐通过小写的单一字母做 group 目录
| ├── components // group 下公用的组件集合
| ├── Login // group 下的页面 Login
| ├── Register // group 下的页面 Register
| └── util.ts // 这里可以有一些共用方法之类,不做推荐和约束,看业务场景自行做组织
└── \* // 其它页面组件代码

APP.ts 配置

数据请求

Umijs 项目中的请求封装 | XIAKEMING

动态路由

路由配置

UmiJS3 路由配置

UmiJS4 路由配置

关于什么是动态路由动态菜单的区别

简单来说

动态路由就是控制页面访问的链接,当链接不存在时直接 404,可以很好的控制用户权限问题

动态菜单就是在已有的路由基础上控制哪个菜单渲染到页面上显示,没有显示的菜单依然可以访问,需要通过权限判断来控制页面要不要显示 403

当然了这两者使用其一就可以很好的控制菜单权限,当是也可以结合起来使用,效果也不错。

动态路由方案

app.ts

let extraRoutes: any; //存储服务器路由

/**需要在这里修改路由,直接操作routes就好不需要返回 */
export async function patchClientRoutes({ routes }: any) {
  // element为路由对应组件,需要通过require()来加载或者import() 注意import是异步加载的
  extraRoutes.children[1].element =
    // 在require动态加载时不能直接将完整路径传进去需要使用拼接的方式也就是./pages必须拼接在外面,
    // 因为如果写全部路径时打包工具会识别不了
    require(`./pages/${extraRoutes.children[1].component}`).default();
  // 为什么要加到path:'/'的路由下才起作用 不清楚可以打印看看
  routes[2].children.push(extraRoutes);
  console.log(extraRoutes.children[1].component);
}

export async function render(oldRender: any) {
  // getRoutes 请求路由
  await getRoutes({ userId: "001" })
    .then((res) => {
      extraRoutes = res;
      oldRender();
    })
    .catch((rej) => {
      console.log(rej, "rej");
    });
}

请求 mock

export default {
  "POST /api/myroutes": async (req: ReqRoutes, res: Response) => {
    const { userId } = req;
    res.send({
      name: "系统管理",
      path: "/system",
      // 权限配置
      access: "canUser",
      children: [
        {
          path: "/system",
          redirect: "/system/menu",
        },
        {
          // 如果不返回name菜单不会渲染,但是还可以访问
          name: "菜单配置",
          path: "/system/menu",
          component: "SystemManage/MenuConfigure",
        },
      ],
    });
  },
};

请求 API

/** 获取路由 POST /api/myroutes */
export async function getRoutes(
  body: API.Routes,
  options?: { [key: string]: any }
) {
  return request<Record<string, any>>("/api/myroutes", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    data: body,
    ...(options || {}),
  });
}

动态菜单方案

1、动态菜单需要提前配置好路由,不管是本地配好,还是通过服务器请求

2、在 app.ts 中配置以下文件

// ProLayout 支持的api https://procomponents.ant.design/components/layout
export const layout: RunTimeLayoutConfig = ({
  initialState,
  setInitialState,
}) => {
  return {
    menu: {
      // 请求参数 当参数改变时会重新执行请求
      params: {
        userId: initialState?.currentUser?.userid,
      },
      request: async (params, defaultMenuData) => {
        const response = await fetch("/api/menu", {
          method: "POST",
          body: JSON.stringify(params),
          headers: {
            "Content-Type": "application/json",
          },
        });
        const menuData = await response.json();
        return menuData;
      },
      locale: true, // 将 locale 设置为 true
    },
  };
};

权限管理

数据流


文章作者: Ming Hui
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Ming Hui !
评论
  目录