我个人喜欢从实战入手框架,在对react文档功能有了基本的了解以后,使用ant-design-pro直接上手熟悉react的功能。
相关版本:
react 17.0.0
ant-design 4.14.0
ant-design-pro 5.0.0
安装ant-design-pro并熟悉项目结构
首先通过脚手架下载Ant Design Pro
然后将项目启动,根据本地项目结构参考Ant Design Pro 文件夹结构了解每个文件夹的作用。
根据Ant Design Pro的文档安装模板。
1.1 安装ant-design-pro
# 初始化脚手架
$ yarn create umi myapp
# 选择 ant-design-pro
? Select the boilerplate type (Use arrow keys)
❯ ant-design-pro - Create project with a layout-only ant-design-pro boilerplate
, use together with umi block.
app - Create project with a simple boilerplate, support typescript
.
plugin - Create a umi plugin.
# 选择开发语言(TypeScript)
? 🤓 Which language do you want to use? (Use arrow keys)
TypeScript
❯ JavaScript
# simple 是基础模板, complete 包含 antd 的集成方案(simple)
? 🚀 Do you need all the blocks or a simple scaffold? (Use arrow keys)
❯ simple
complete
# 安装依赖
$ cd myapp && yarn
# 启动项目
yarn start
1.2 重要的文件目录
熟悉的配方,熟悉的结构。
config
umi 配置,包含路由,构建等配置
mock
本地模拟数据
src
源码目录
基于Webpack的项目基本都是上述三个目录,配置工程、本地数据模拟、项目源码。 其他的文件都是本地工程用到的描述或配置文件,根据自己需求改动。
修改系统配置,删减无用内容
虽然安装了Ant Design Pro模板版本,但是它还是会内置一些东西,需要将其删除
修改系统全局设置
模板默认的配色及结构和预期不一致,需要修改配置调整为常规方案。文件位置 config/defaulltSetting.ts
此处需要打开ant-design-pro预览网站,通过右侧配置,将UI调整为目标样子后复制设置到自己的项目中。
export default {
"navTheme": "dark",
"primaryColor": "#1890ff",
"layout": "side",
"contentWidth": "Fluid",
"splitMenus": false,
"fixedHeader": true,
"fixSiderbar": true,
colorWeak: false,
title: '基础管理系统',
pwa: false,
logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
iconfontUrl: '',
};
删除国际化
作为入门学习,而且在实际工作中很少用到国际化,需移除国际化,Ant Design Pro提供了命令可一次性移除所有国际化。
# 运行下面命令移除国际化
$ yarn i18n-remove
【注意】删除后config
目录下会生成routes.ts
文件,将内容拷贝到routes.js
文件中即可。否则项目会报错。
移除顶部帮助文档链接和搜索
在src/app.jsx
文件中,有个layout
导出,顾名思义就是基础布局。
在其配置项中有rightContentRender
配置项,用于配置右侧内容,此处就是顶栏右侧内容。
根据组件引用,在src/components/RightContent/index.jsx
中找到右侧内容的jsx渲染代码。
return (
<Space className={className}>
<HeaderSearch
className={`${styles.action} ${styles.search}`}
placeholder="站内搜索"
defaultValue="umi ui"
options={[
{
label: <a href="https://umijs.org/zh/guide/umi-ui.html">umi ui</a>,
value: 'umi ui',
},
{
label: <a href="next.ant.design">Ant Design</a>,
value: 'Ant Design',
},
{
label: <a href="https://protable.ant.design/">Pro Table</a>,
value: 'Pro Table',
},
{
label: <a href="https://prolayout.ant.design/">Pro Layout</a>,
value: 'Pro Layout',
},
]}
// onSearch={value => {
// console.log('input', value);
// }}
/>
<span
className={styles.action}
onClick={() => {
window.open('https://pro.ant.design/docs/getting-started');
}}
>
<QuestionCircleOutlined />
</span>
<Avatar />
</Space>
);
上述代码中的HeaderSearch
就是顶栏搜索,QuestionCircleOutlined
则是问号图标。
删除相应代码即可
左侧菜单OpenAPI文档和业务组件文档
在src/app.jsx
的layout
导出代码,其中的links
配置用于配置侧边菜单的底部链接,删除相应代码即可。
// 相关引用和变量
import { history, Link } from 'umi';
import { BookOutlined, LinkOutlined } from '@ant-design/icons';
const isDev = process.env.NODE_ENV === 'development';
// 布局配置导出
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
return {
rightContentRender: () => <RightContent />,
disableContentMargin: false,
waterMarkProps: {
content: initialState?.currentUser?.name,
},
footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history;
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
}
},
// 此配置用于渲染右侧菜单底部链接
// links: isDev
// ? [
// <Link to="/umi/plugin/openapi" target="_blank">
// <LinkOutlined />
// <span>OpenAPI 文档</span>
// </Link>,
// <Link to="/~docs">
// <BookOutlined />
// <span>业务组件文档</span>
// </Link>,
// ]
// : [],
menuHeaderRender: undefined,
// 自定义 403 页面
// unAccessible: <div>unAccessible</div>,
...initialState?.settings,
};
};
底部链接和版权声明
在src/app.jsx
的layout
导出代码,启用的footerRender
用于配置系统底部区域。直接删除配置即可。
// 布局配置导出
export const layout: RunTimeLayoutConfig = ({ initialState }) => {
return {
rightContentRender: () => <RightContent />,
disableContentMargin: false,
waterMarkProps: {
content: initialState?.currentUser?.name,
},
// 此配置用于渲染底部区域
// footerRender: () => <Footer />,
onPageChange: () => {
const { location } = history;
// 如果没有登录,重定向到 login
if (!initialState?.currentUser && location.pathname !== loginPath) {
history.push(loginPath);
}
},
menuHeaderRender: undefined,
// 自定义 403 页面
// unAccessible: <div>unAccessible</div>,
...initialState?.settings,
};
};
如果需要底部内容且需要修改成自己的文案,根据Footer
组件的引用在src/Footer/index.jsx
中找到footer的代码,修改相应属性值即可
export default () => {
const defaultMessage = '我的系统';
const currentYear = new Date().getFullYear();
return (
<DefaultFooter
copyright={`${currentYear} ${defaultMessage}`}
links={[]}
/>
);
};
【注意】links置空必须传空数组
熟悉UmiJS
Ant Design Pro使用了UmiJS工具搭建的工程,UmiJs是什么? 访问UmiJS官网看到如下标语
插件化的企业级前端应用框架。
怎么又一个框架?和React有什么关系?
在首页的描述中,发现下面这句话
Umi 内置了路由、构建、部署、测试等,仅需一个依赖即可上手开发。并且还提供针对 React 的集成插件集,内涵丰富的功能,可满足日常 80% 的开发需求。
可以简单理解为:对React及其插件进行包装的框架。
在UmiJS介绍中有如下描述
为什么不是? create-react-app create-react-app 是基于 webpack 的打包层方案,包含 build、dev、lint 等,他在打包层把体验做到了极致,但是不包含路由,不是框架,也不支持配置。所以,如果大家想基于他修改部分配置,或者希望在打包层之外也做技术收敛时,就会遇到困难。
next.js next.js 是个很好的选择,Umi 很多功能是参考 next.js 做的。要说有哪些地方不如 Umi,我觉得可能是不够贴近业务,不够接地气。比如 antd、dva 的深度整合,比如国际化、权限、数据流、配置式路由、补丁方案、自动化 external 方面等等一线开发者才会遇到的问题。
综上大概可以把它理解成是包含react及其插件、支持脚手架功能及服务端渲染的框架。
Ps. 就是把脚手架功能和服务端渲染的功能封装在一起,同时封装了react的插件集,有种大而全的意思。我个人还是喜欢小而美的东西,这一次我投vue-cli一票。
既然是个框架,那么项目结构应该和原React不一样了,先熟悉一下这个框架,毕竟要基于Ant Design Pro学习React么,Ant Design Pro用它了也没必要非自己搭一套东西。
目录结构
Ant Design Pro就是基于UmiJS搭建的,现有的目录就是UmiJS的目录结构,先熟悉一下目录:
src/.umi
临时文件目录,比如入口文件、路由等,都会被临时生成到这里。不要提交 .umi 目录到 git 仓库,他们会在 umi dev 和 umi build 时被删除并重新生成。这个目录是框架生成的,我们不用管它。
src/app.ts
运行时配置文件,可以在这里扩展运行时的能力,比如修改路由、修改 render 方法等。类似入口文件
src/layouts/index.jsx
约定式路由时的全局布局文件。项目里没有这个目录,不管它。
src/pages
目录 所有路由组件存放在这里。 页面组件放置的位置,类似Vue的views
目录
目录的作用和其命名基本一致。
配置
UmiJS的配置文件在config/config.js
文件中,里面内置了一些配置,可根据需求自行修改。
全部配置参考UmiJS配置,本次不做修改,后续跟进需要在修改。
运行时配置
约定 src/app.jsx
为运行时配置,可以理解为入口文件
modifyClientRenderOpts
修改 clientRender 参数。比如在微前端里动态修改渲染根节点。暂时不考虑微前端,先不管它。
patchRoutes
修改路由。 这个配置暂时可以理解为用于动态添加路由,后续根据需要在试试。
render
覆写 render。比如用于渲染之前做权限校验。这个相当于钩子函数,可以做一些拦截。
onRouteChange
在初始加载和路由切换时做一些事情。比如用于做埋点统计。类似于路由钩子函数,后面应该会用到。
rootContainer
修改交给 react-dom 渲染时的根组件。这个配置估计用不到。
路由
在配置文件中通过 routes 进行配置,格式为路由信息的数组。 配置文件位置config/routes.ts
path
路径,和Vue-router一样的。
component
用于渲染的 React 组件路径。这个和Vue不太一样,估计是UmiJS动态加载的,好处是不用写import了,坏处是IDE路径匹配没用了,万一组件换个位置就gg了。
exact
是否严格匹配,这个Vue没有哈,不过一般也不严格匹配。
routes
配置子路由,Vue-router的是children,我个人更觉得children更加语义化。
redirect
配置路由跳转。重定向,路由都有
wrappers
配置路由的高阶组件封装。 这个高阶组件是React特有的。
title
路由的标题
Ps. 😭 居然没有支持自定义数据的配置,之前Vue页面级组件复用那一套不能玩了么,又得另辟蹊径了。。。
约定式路由
如果没有 routes 配置,Umi 会进入约定式路由模式,然后分析 src/pages
目录拿到路由配置。
动态路由
动态可选路由
嵌套路由
全局 layout
不同的全局 layout
404 路由
权限路由
扩展路由属性
这个挺好,就是得团队成员配合。不配置路由,只修改文件位置就自动生成路由,还是不错的。权限分散到组件里,创意不错。
其他配置
插件
暂时用不到
页面跳转
声明式和命令式,和Vue-router一样。
HTML 模板
类似html入口文件,主要内容就是root根节点和刷新时的DOM动画。
Mock 数据
模拟数据的,拦截返回数据就行么,没什么难点。
环境变量
基于cross-env可以设置不同环境的环境变量
命令行工具
本地开发、打包、校验等等命令
完善项目工程
对UmiJS有了基本的了解之后,大概知道模板每个文件的作用了,下面开始着手整理工程模板。
添加测试、预生产、生产环境变量
Ant Design Pro的环境变量设置和Vue不一样,它是在config
目录下通过config.*.ts
进行配置的。
.
├── config
│ ├── config.dev.ts # 开发环境
│ ├── config.test.ts # 测试环境
│ ├── config.pre.ts # 预生产环境
│ └── config.prod.ts # 生产环境
内容如下
import { defineConfig } from 'umi';
export default defineConfig({
define: {
BASE_URL: '服务器接口基础路径',
},
});
调整Pages目录
由于之前Vue的习惯,现在Ant Design Pro的pages目录太乱了,对它的内容进行整理,无用内容删除。
.
├── pages
│ ├── auth # 账户页面(登陆、注册等)
│ ├── error # 异常页面(401、404、500等)
│ ├── home # 首页
│ └── document.ejs # 模板
修改路由配置
文件调整完了,会造成引用出错,现在调整routes配置
export default [
{ path: '/', component: './home/Home' },
{ path: '/auth/login', name: '登录', layout: false, component: './auth/Login' },
{ component: './error/404' },
]
删除了user的嵌套路由。每个嵌套路由都需要404的路由,因此直接使用一层级路由即可。
结语
通过对ant-design-pro的处理,收获的东西如下:
-
系统配置的位置为
config/defaultSetting.ts
。 -
项目入口文件为
src/app.jsx
。 -
src/app.jsx
中的layout
导出项用于配置系统基础布局。 -
UmiJs的功能确实很强大,但是有些设计不是很合理(例如.umi目录,html模板位置等)。