docs/cheatsheet.zh-CN.md
创建项目:
git clone --depth 1 https://github.com/ant-design/ant-design-pro.git my-project
cd my-project
npm install
项目提供两种模式:
切换精简模式:
git add -A && git commit -m "chore: save before simple" # 先提交,以便回退
npm run simple # 删除示例页面和多余依赖
npm install # 更新依赖
💡 建议先用完整模式熟悉项目结构,再切换精简模式开始开发。
目录结构:
├── config/ # 配置文件(路由、代理、主题)
│ ├── config.ts # 主配置
│ ├── routes.ts # 路由配置
│ ├── defaultSettings.ts # 布局主题设置
│ └── proxy.ts # 开发代理配置
├── mock/ # Mock 数据
├── src/
│ ├── components/ # 公共组件
│ ├── locales/ # 国际化资源
│ ├── models/ # 全局数据模型
│ ├── services/ # API 服务层
│ ├── utils/ # 工具函数
│ ├── access.ts # 权限定义
│ └── app.tsx # 运行时配置
├── docs/ # 项目文档
└── types/ # 类型声明
常用命令:
| 命令 | 说明 |
|---|---|
npm start | 启动开发服务器(UMI_ENV=dev,带 Mock) |
npm run dev | 启动开发服务器(UMI_ENV=dev,无 Mock) |
npm run start:no-mock | 无 Mock 启动 |
npm run start:pre | 预发布环境启动 |
npm run start:test | 测试环境启动 |
npm run build | 构建生产产物 |
npm run preview | 预览已构建产物(需先 npm run build,端口 8000) |
npm run preview:build | 构建并本地预览(端口 8000) |
npm run deploy | 构建并部署到 GitHub Pages |
npm run analyze | 构建产物体积分析 |
npm run lint | 代码检查(Biome + TypeScript) |
npm run biome | Biome 自动修复 |
npm test | 运行测试 |
npm run test:coverage | 测试覆盖率 |
npm run test:update | 更新测试快照 |
npm run tsc | 类型检查(不生成文件) |
npm run i18n-remove | 移除国际化(locale=zh-CN) |
npm run record | 录制登录场景请求数据 |
npm run openapi | 根据 OpenAPI 生成 API 代码 |
npm run simple | 精简模式(删除示例页面和多余依赖) |
💡
UMI_ENV用于切换环境配置,对应config/proxy.ts中的不同代理规则。
💡
npm run simple会删除示例页面(dashboard、form、list 等)和多余依赖(plots 等),替换为精简路由,适合从零开始开发。建议先提交代码,以便需要时回退。
构建工具: 本项目使用 utoopack(基于 Turbopack 的新一代打包器)作为默认构建工具,通过 config/config.ts 中的 utoopack 字段配置。utoopack 兼容 Webpack 配置格式,支持 module.rules 配置自定义加载器。
路由配置 位于 config/routes.ts:
export default [
{
path: '/welcome',
name: 'welcome', // 对应 menu.welcome 国际化 key
icon: 'home',
component: './Welcome',
},
{
path: '/admin',
name: 'admin',
icon: 'crown',
access: 'canAdmin', // 路由级权限控制
routes: [...],
},
{ path: '/', redirect: '/dashboard/analysis' },
{ component: '404', path: './*' },
];
路由导航:
import { useNavigate, useParams, useLocation } from '@umijs/max';
const navigate = useNavigate();
navigate('/dashboard'); // 跳转
navigate(-1); // 后退
const { id } = useParams(); // 获取动态参数 /user/:id
const location = useLocation(); // 当前路由信息
菜单与权限联动: 路由配置中 access 字段控制菜单可见性,未授权路由不会出现在菜单中。
💡
name字段自动映射为menu.xxx国际化 key,在src/locales/中配置翻译。
→ 更多内容见 umi 路由文档、Umi Max 布局与菜单
ProLayout 配置 位于 config/defaultSettings.ts:
export default {
navTheme: 'light', // 导航主题:light / dark
colorPrimary: '#1890ff', // 主题色
layout: 'mix', // 布局模式:side / top / mix
contentWidth: 'Fluid', // 内容宽度:Fluid / Fixed
fixSiderbar: true, // 固定侧边栏
};
布局模式:
side — 左侧导航top — 顶部导航mix — 顶部 + 侧边混合导航页面容器:
import { PageContainer } from '@ant-design/pro-components';
const Page = () => (
<PageContainer
header={{ title: '页面标题' }}
content="页面描述"
>
</PageContainer>
);
自定义区域: 右上角 src/components/RightContent,底部 src/components/Footer。
→ 更多内容见 Umi Max 布局与菜单
useModel — 轻量全局状态: 在 src/models/ 下创建文件即自动注册:
// src/models/counter.ts
import { useState } from 'react';
export default function useCounter() {
const [count, setCount] = useState(0);
const increment = () => setCount(c => c + 1);
return { count, increment };
}
// 任意组件中使用
import { useModel } from '@umijs/max';
const { count, increment } = useModel('counter');
useRequest — 数据请求:
import { useRequest } from '@umijs/max';
const { data, loading, error } = useRequest(getUserInfo);
React Query — 服务端状态管理:
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
// 查询
const { data, isLoading } = useQuery({
queryKey: ['user', id],
queryFn: () => getUser(id),
});
// 变更
const mutation = useMutation({
mutationFn: updateUser,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['user'] });
},
});
初始状态 — getInitialState: 在 src/app.tsx 中定义,全局可访问:
// src/app.tsx
export async function getInitialState() {
const currentUser = await fetchUserInfo();
return { currentUser };
}
// 组件中使用
import { useModel } from '@umijs/max';
const { initialState } = useModel('@@initialState');
💡
getInitialState在应用启动时执行一次,适合获取全局信息(如用户身份、权限)。
→ 更多内容见 Umi Max 数据流
请求配置 位于 src/app.tsx:
export const request: RequestConfig = {
baseURL: 'https://api.example.com',
timeout: 10000,
requestInterceptors: [], // 请求拦截器
responseInterceptors: [], // 响应拦截器
};
错误处理 位于 src/requestErrorConfig.ts,可自定义错误码映射和提示逻辑。
使用请求:
import { request } from '@umijs/max';
// GET
const data = await request('/api/users', { params: { page: 1 } });
// POST
await request('/api/users', { method: 'POST', data: { name: 'test' } });
OpenAPI 代码生成:
npm run openapi
根据 config/oneapi.json 自动生成 src/services/ 下的 API 调用代码。
💡 生成后的代码直接用
import { request } from '@umijs/max'发起请求,无需手动封装。
→ 更多内容见 Umi Max 请求
定义权限 在 src/access.ts:
export default function access(initialState: { currentUser?: API.CurrentUser }) {
const { currentUser } = initialState;
return {
canAdmin: currentUser?.access === 'admin',
canUser: !!currentUser,
};
}
路由级权限: 在路由配置中添加 access 字段:
{ path: '/admin', access: 'canAdmin' }
组件级权限:
import { Access, useAccess } from '@umijs/max';
// 声明式
<Access accessible={access.canAdmin}>
<AdminPanel />
</Access>
// 命令式
const access = useAccess();
if (access.canAdmin) { /* ... */ }
→ 更多内容见 Umi Max 权限
配置 在 config/config.ts:
locale: {
default: 'zh-CN',
antd: true, // 同步 antd 组件语言
baseNavigator: true, // 跟随浏览器语言
},
文件结构:
src/locales/
├── zh-CN.ts # 中文入口
├── zh-CN/
│ ├── menu.ts # 菜单翻译
│ ├── pages.ts # 页面翻译
│ └── ...
├── en-US.ts # 英文入口
└── en-US/
└── ...
使用方式:
import { useIntl, FormattedMessage } from '@umijs/max';
// Hook 方式
const intl = useIntl();
intl.formatMessage({ id: 'menu.welcome' });
// 组件方式
<FormattedMessage id="menu.welcome" />
切换语言:
import { setLocale } from '@umijs/max';
setLocale('en-US', false); // false = 不刷新页面
→ 更多内容见 Umi Max 国际化
CSS Modules: 文件命名为 *.module.less 或 *.module.css:
/* example.module.less */
.container { padding: 24px; }
.title { font-size: 16px; }
import styles from './example.module.less';
<div className={styles.container} />
antd-style(CSS-in-JS):
import { createStyles } from 'antd-style';
const useStyles = createStyles(({ token, css }) => ({
card: css`
background: ${token.colorBgContainer};
border-radius: ${token.borderRadiusLG}px;
`,
}));
const { styles } = useStyles();
<div className={styles.card} />
Tailwind CSS(v4): 直接在 className 中使用:
<div className="flex items-center gap-4 p-6 rounded-lg bg-white dark:bg-[#141414]" />
动态主题: 在 config/config.ts 的 antd 配置中设置:
antd: {
configProvider: {
theme: {
token: {
colorPrimary: '#1890ff',
borderRadius: 6,
},
},
},
},
开发环境可通过右下角 SettingDrawer 实时切换主题。
💡 三种样式方案可以共存:Tailwind 适合布局、CSS Modules 适合组件样式、antd-style 适合需要消费主题 token 的场景。
→ 更多内容见 umi 样式文档、Umi Max antd 动态主题
Jest 测试:
npm test # 运行所有测试
npm run test:coverage # 带覆盖率报告
npm run test:update # 更新快照
测试文件放在对应组件目录下,命名为 *.test.ts(x)。
Mock 数据: 在 mock/ 目录下创建文件:
// mock/user.ts
export default {
'GET /api/currentUser': { name: 'Serati Ma', access: 'admin' },
'POST /api/login': (req, res) => { res.end('ok'); },
};
Umi 自动注册 mock,开发模式下生效。
代理配置 位于 config/proxy.ts:
export default {
dev: {
'/api/': {
target: 'http://localhost:8080',
changeOrigin: true,
},
},
};
💡 用
MOCK=none启动可跳过 Mock,直接代理到后端:npm run start:no-mock。
Q: 如何关闭 Mock?
npm run start:no-mock 或 cross-env MOCK=none max dev
Q: 如何修改主题色?
修改 config/defaultSettings.ts 的 colorPrimary,开发时可用 SettingDrawer 实时调整。
Q: 如何添加新页面?
src/pages/ 下创建组件 2. 在 config/routes.ts 添加路由 3. 在 src/locales/ 添加菜单翻译(如需)Q: 如何添加全局状态?
在 src/models/ 下创建文件,导出自定义 Hook,组件中通过 useModel('文件名') 使用。
Q: 如何部署?
npm run build 生成 dist/ 目录,部署到任意静态服务器。配置 publicPath 处理非根目录部署。npm run deploy 会自动构建并发布到 GitHub Pages(推送到 gh-pages 分支)。
Q: 如何使用 OpenAPI 代码生成?
config/config.ts 配置 openAPI 2. 运行 npm run openapi 3. 自动生成 src/services/ 下的代码→ 更多内容见 umi FAQ