开发者:蚂蚁【支付宝,蚂蚁金融】基于React 研发可插拔的企业级 react 应用框架。
通过约定、自动生成和解析代码等方式来辅助开发,减少我们开发者的代码量。
路由做到按需加载
github https://github.com/ant-design/ant-design-pro
https://github.com/sorrycc/blog/issues/66
https://zhuanlan.zhihu.com/p/142412204

Ant Design Pro 使用 Umi 作为开发工具,建议你先查看 Umi 的常见问题

  1. # umijs 4x
  2. yarn create umi my-app
  3. # umijs 3x
  4. yarn create @umijs/umi-app

antd pro5x

https://github.com/ant-design/ant-design-pro/tree/v5.2.0
https://v5-pro.ant.design/zh-CN/docs/folder
https://github.com/websemantics/awesome-ant-design

集成的技术点

集成了 pro-layout 组件

antd pro4x

antd pro4x 常见问题 https://v4-pro.ant.design/docs/faq-cn
antd pro4x文档 https://v4-pro.ant.design/docs/available-script-cn

  1. npx umi block add UserRegister --path=/user/user-register

image.png

umi3 可以用 js,把 .umirc.tsx直接改为 .umirc.js, pages下的 ts修改为 js
官方默认生成 ts项目,给人错觉不能使用 js开发
.umirc.js 配置
项目开发,不要修改 pages/.umi目录

$id.js 动态路由 /:id,umi2
[id].js umi3动态路由
umi3 手动新增文件,要把 .umirc.js的里面的 routes给注释掉

create page

  1. create umi
  2. create page index.js
  3. 会自动添加到路由,直接新建的目录,需要自己手动添加到路由
  4. npx umi g page index 生成 index.js index.css
  5. src/pages/index.js
  6. src/pages/index.css
  7. npx umi g page class/index
  8. src/pages/class/index.js
  9. src/pages/class/index.css

创建 umi项目

  1. 请在空文件夹中使用,或者使用 yarn create umi myapp ```jsx npm create umi myapp 选择 ant-design-pro 选择 V5

npm install

npm start # localhost:8000

npm run umi # 区块布局

  1. umimock 是对 express的封装
  2. <a name="k0zMV"></a>
  3. ## umi block list
  4. [https://github.com/ant-design/pro-blocks](https://github.com/ant-design/pro-blocks)<br />[pro-blocks-master.zip](https://www.yuque.com/attachments/yuque/0/2020/zip/112859/1606634535226-2e00eb7c-504b-4abc-89fb-1d1b03631b3f.zip?_lake_card=%7B%22src%22%3A%22https%3A%2F%2Fwww.yuque.com%2Fattachments%2Fyuque%2F0%2F2020%2Fzip%2F112859%2F1606634535226-2e00eb7c-504b-4abc-89fb-1d1b03631b3f.zip%22%2C%22name%22%3A%22pro-blocks-master.zip%22%2C%22size%22%3A2715331%2C%22ext%22%3A%22zip%22%2C%22source%22%3A%22%22%2C%22status%22%3A%22done%22%2C%22download%22%3Atrue%2C%22type%22%3A%22application%2Fzip%22%2C%22mode%22%3A%22title%22%2C%22uid%22%3A%221606634534186-0%22%2C%22progress%22%3A%7B%22percent%22%3A99%7D%2C%22percent%22%3A0%2C%22id%22%3A%22aV3wK%22%2C%22card%22%3A%22file%22%7D)
  5. umi block add 报错<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/112859/1606634606313-a883095a-bb72-4f65-82ff-144e8bba04f2.png#averageHue=%233c3e48&height=289&id=Cx09t&originHeight=578&originWidth=2192&originalType=binary&ratio=1&rotation=0&showTitle=false&size=764660&status=done&style=none&title=&width=1096)<br />默认仓库数 gitee.com,下载需要登录,解决方法:
  6. 1. 进入 /Users/lulongwen/.umi3/blocks/github.com/umijs/umi-blocks/,查看 git remote
  7. ```bash
  8. git remote -v
  9. origin https://gitee.com/umijs/umi-blocks.git (fetch)
  10. origin https://gitee.com/umijs/umi-blocks.git (push)
  11. # 修改 git remote
  12. git remote set-url origin https://github.com/ant-design/pro-blocks.git

缺点:下载速度慢些

  1. 下载 https://github.com/ant-design/pro-blocks 直接把模板移动到 /Users/lulongwen/.umi3/blocks/github.com/umijs/umi-blocks/ 目录就好了

model数据流

umijs@4.x,内置了一套和 hox 一模一样的数据流方案,特点

  1. 采用约定式目录结构,不用专门写 createStore ,而是自动帮我们引入了所有 model 目录下的 hooks,并注册。
  2. 在页面中则是通过统一的 useModel,通过其自动生成的 namespace 引用,比如 useModel(‘product’)。
  3. 这也导致了依赖不明确的问题,umi4 还特地通过编写插件的方式解决跳转问题。
    1. useModel(‘product’) 必须要通过装插件才能点击跳转
  4. 必须要在 umijs@4.x 体系下才能使用,无法快速复制迁移到其它的框架下使用

blockConfig

genBlockConfig.js https://github.com/ant-design/pro-blocks

  1. const fs = require('fs');
  2. const { join } = require('path');
  3. const gitUrl = 'https://github.com/ant-design/pro-blocks';
  4. const menuData = {
  5. home: '首页',
  6. Empty: '空白',
  7. login: '登录',
  8. register: '注册',
  9. 'register/result': '注册结果',
  10. dashboard: 'Dashboard',
  11. 'dashboard/analysis': '分析页',
  12. 'dashboard/monitor': '监控页',
  13. 'dashboard/workplace': '工作台',
  14. 'exception/403': '403',
  15. 'exception/404': '404',
  16. 'exception/500': '500',
  17. form: '表单页',
  18. 'user/login': '登录页',
  19. 'user/register': '注册页',
  20. 'user/register/result': '注册结果页',
  21. 'form/basic/form': '基础表单',
  22. 'form/step/form': '分步表单',
  23. 'form/advanced/form': '高级表单',
  24. list: '列表页',
  25. 'list/table/list': '查询表格',
  26. 'list/basic/list': '标准列表',
  27. 'list/card/list': '卡片列表',
  28. 'list/search': '搜索列表',
  29. 'list/search/articles': '搜索列表(文章)',
  30. 'list/search/projects': '搜索列表(项目)',
  31. 'list/search/applications': '搜索列表(应用)',
  32. profile: '详情页',
  33. 'profile/basic': '基础详情页',
  34. 'profile/advanced': '高级详情页',
  35. result: '结果页',
  36. 'result/success': '成功页',
  37. 'result/fail': '失败页',
  38. exception: '异常页',
  39. 'exception/not-permission': '403',
  40. 'exception/not-find': '404',
  41. 'exception/server-error': '500',
  42. 'exception/trigger': '触发错误',
  43. account: '个人页',
  44. 'account/center': '个人中心',
  45. 'account/settings': '个人设置',
  46. 'account/trigger': '触发报错',
  47. 'account/logout': '退出登录',
  48. editor: '图形编辑器',
  49. 'editor/flow': '流程编辑器',
  50. 'editor/mind': '脑图编辑器',
  51. 'editor/koni': '拓扑编辑器',
  52. };
  53. const tagsKey = {
  54. list: '列表',
  55. search: '搜索',
  56. articles: 'remove',
  57. table: '表格',
  58. form: '表单',
  59. step: 'remove',
  60. basic: '基本',
  61. card: 'remove',
  62. applications: 'remove',
  63. projects: 'remove',
  64. 404: 'remove',
  65. 403: 'remove',
  66. 500: 'remove',
  67. profile: '详情',
  68. advanced: '高级',
  69. result: '结果',
  70. fail: 'remove',
  71. success: 'remove',
  72. user: '用户',
  73. login: '登录',
  74. register: '注册',
  75. account: 'remove',
  76. center: '个人中心',
  77. settings: '个人设置',
  78. dashboard: 'dashboard',
  79. analysis: 'remove',
  80. monitor: 'remove',
  81. workplace: 'remove',
  82. editor: '图形编辑',
  83. flow: 'remove',
  84. koni: 'remove',
  85. mind: 'remove',
  86. exception: '异常',
  87. };
  88. /**
  89. * 从文件数组映射为 pro 的路由
  90. * @param {*} name
  91. */
  92. const genBlockName = (name) =>
  93. name
  94. .match(/[A-Z]?[a-z]+|[0-9]+/g)
  95. .map((p) => p.toLowerCase())
  96. .join('/');
  97. /**
  98. * 从文件数组映射为 tags 列表
  99. * @param {*} name
  100. */
  101. const genBlockTags = (name) =>
  102. Array.from(new Set(name.match(/[A-Z]?[a-z]+|[0-9]+/g).map((p) => p.toLowerCase())))
  103. .map((key) => tagsKey[key] || key)
  104. .filter((key) => key !== 'remove');
  105. const getFeature = (filePath) => {
  106. const feature = ['antd'];
  107. const srcPath = join(filePath, 'src');
  108. const localesPath = join(srcPath, 'locales');
  109. if (fs.existsSync(localesPath)) {
  110. feature.push('i18n');
  111. }
  112. const modalTsxPath = join(srcPath, 'model.tsx');
  113. const modalTsPath = join(srcPath, 'model.ts');
  114. const modalJsPath = join(srcPath, 'model.js');
  115. const modalJsxPath = join(srcPath, 'model.jsx');
  116. if (
  117. fs.existsSync(modalTsxPath) ||
  118. fs.existsSync(modalTsPath) ||
  119. fs.existsSync(modalJsPath) ||
  120. fs.existsSync(modalJsxPath)
  121. ) {
  122. feature.push('dva');
  123. }
  124. return feature;
  125. };
  126. /**
  127. * 遍历文件地址
  128. * @param path
  129. */
  130. const getFolderTreeData = (filePath) => {
  131. const files = fs.readdirSync(filePath);
  132. const blockList = files
  133. .map((fileName) => {
  134. const status = fs.statSync(join(filePath, fileName));
  135. if (status.isDirectory() && fileName.indexOf('.') !== 0 && fileName !== 'EmptyPage') {
  136. const absPkgPath = join(filePath, fileName, 'package.json');
  137. if (fs.existsSync(absPkgPath)) {
  138. const pkg = require(absPkgPath);
  139. return {
  140. name: menuData[genBlockName(fileName)],
  141. key: fileName,
  142. description: pkg.description,
  143. url: `${gitUrl}/tree/master/${fileName}`,
  144. path: fileName,
  145. features: getFeature(join(filePath, fileName)),
  146. img: `https://raw.githubusercontent.com/ant-design/pro-blocks/master/${fileName}/snapshot.png?raw=true`,
  147. tags: genBlockTags(fileName),
  148. previewUrl: `https://preview.pro.ant.design/${genBlockName(fileName)}`,
  149. };
  150. }
  151. }
  152. return undefined;
  153. })
  154. .filter((obj) => obj);
  155. blockList.unshift({
  156. key: 'EmptyPage',
  157. name: '空白页面',
  158. description: '一个空白的页面,一切都从这里开始!',
  159. url: 'https://github.com/ant-design/pro-blocks/tree/master/EmptyPage',
  160. path: 'NewPage',
  161. features: ['antd'],
  162. img:
  163. 'https://raw.githubusercontent.com/ant-design/pro-blocks/master/EmptyPage/snapshot.png?raw=true',
  164. tags: ['空白页'],
  165. previewUrl: 'https://preview.pro.ant.design',
  166. });
  167. return blockList;
  168. };
  169. fs.writeFileSync(
  170. join(__dirname, '..', 'umi-block.json'),
  171. JSON.stringify({ list: getFolderTreeData(join(__dirname, '../')) }, null, 2),
  172. );

umi-ui

https://github.com/umijs/umi-ui
不推荐使用
73431180-c77ab400-437a-11ea-9baa-ebd00109b1d0.png