本文基于 Ant Design Pro 1.1.0 版本,参考前请注意版本信息。
Ant Design Pro 是蚂蚁金服团队在 Ant Design 的设计规范与组件库基础上推出的一套 React 实现的企业级中后台前端/设计解决方案。
上手
使用方法是直接 clone 其 GitHub 仓库然后执行 npm install
,或是安装官方提供的 cli 工具创建项目(但在这过程中也会涉及到 clone 其 GitHub 仓库)。新项目创建后,自带模板页面和工具链,可以快速更改。
git clone --depth=1 https://github.com/ant-design/ant-design-pro.git my-project
cd my-project
npm install
对于开发者而言,要做的当然是将项目快速适配自己的需求。官方提供了中文文档,但其中内容组织较为零碎。在这里和大家简单地以示例页面中的标准列表
为例子,做一个整理,希望能帮助到大家快速上手这个框架。
安装完成后,我们运行 npm run start
来启动本地开发服务器,稍等片刻脚本就会自动完成打包。Ant Design Pro 默认通过只需浏览器单方面就可处理的 HashHistory
来完成路由。如果要切换为 BrowserHistory
,那在 src/index.js
中也有对应的内容可以直接修改,但需要在后端服务器进行相应路由配置。
从路由到组件
我们在左侧的导航栏点击 列表页 > 标准列表
后,可以进入到上面截图所示的页面。导航栏的内容在 src/common/menu.js
中,
/* 导航栏记录
* src/common/menu.js
*/
{
name: '列表页',
icon: 'table',
path: 'list',
children: [{
name: '查询表格',
path: 'table-list',
}, {
name: '标准列表',
path: 'basic-list',
}
...],
}
全局的路由关系是这样一个走向:src/index.js
中通过 app.router(require('./router').default);
,将 src/router.js
绑定到 dva
实例的 router
方法上。而在 src/router.js
中又引入了 src/common/router.js
中的 getRouterData
作为数据源。如果有点绕,不太能一下子看明白,那就直接记下面的结论:
因而,src/common/menu.js
中 path
所指向的路径对应于 src/common/router.js
中的路由记录。
/* 路由记录
* src/common/router.js
*/
export const getRouterData = (app) => {
const routerConfig = {
...,
'/list/basic-list': {
component: dynamicWrapper(app, ['list'], () => import('../routes/List/BasicList')),
},
...,
};
...
}
这里调用了同文件内的 lazy-loading 的动态加载函数 dynamicWrapper
,有 3 个参数,app
为全局 dva
实例,models
为一个带有相关 dva
Model 1 的 Array,component
即为该路由记录对应的实际组件。
const dynamicWrapper = (app, models, component) => {...};
顺藤摸瓜,我们打开 src/routes/List/BasicList.js
,开始考察具体组件。
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import PageHeaderLayout from '../../layouts/PageHeaderLayout';
@connect(({ list, loading }) => ({
list,
loading: loading.models.list,
}))
export default class BasicList extends PureComponent {
componentDidMount() {
this.props.dispatch({
type: 'list/fetch',
payload: {
count: 5,
},
});
}
render() {
return (
<PageHeaderLayout>{/* 具体页面内容 */}</PageHeaderLayout>
);
}
}
@connect 装饰器
首先的组件写法中调用了
dva
所封装的react-redux
的@connect
装饰器,用来接收绑定的list
这个 model 对应的 redux store。注意到这里的装饰器实际除了app.state.list
以外还实际接收app.state.loading
作为参数,这个loading
的来源是src/index.js
中调用的dva-loading
2 这个插件。/* * src/index.js */ import createLoading from 'dva-loading'; app.use(createLoading());
它返回的信息包含了 global、model 和 effect 的异步加载完成情况。
{ "global": true, "models": { "list": false, "user": true, "rule": false }, "effects": { "list/fetch": false, "user/fetchCurrent": true, "rule/fetch": false } }
我们注意到在这里带上 {count: 5}
这个 payload 向 store 进行了一个类型为 list/fetch
的 dispatch,那我们到 src/models/list.js
中就可以找到具体的对应操作。
import { queryFakeList } from '../services/api';
export default {
namespace: 'list',
state: {
list: [],
},
effects: {
*fetch({ payload }, { call, put }) {
const response = yield call(queryFakeList, payload);
yield put({
type: 'queryList',
payload: Array.isArray(response) ? response : [],
});
},
/* ... */
},
reducers: {
queryList(state, action) {
return {
...state,
list: action.payload,
};
},
/* ... */
},
};
后端模拟数据
通过上面的分析,我们可以看到 list/fetch
会造成带上 payload 的对 src/services/api
中 queryFakeList
的一次异步请求。
export async function queryFakeList(params) {
return request(`/api/fake_list?${stringify(params)}`);
}
走到这一步的时候,后端交互开始产生了。我们退到根目录下的 .roadhogrc.mock.js
这个文件。Ant Design Pro 直接沿用了 roadhog 中自带的 mock 功能,在这里我们简单搜索一下就能看到具体的 mock 转发配置。
import { getActivities, getNotice, getFakeList } from './mock/api';
const proxy = {
// ...,
'GET /api/fake_list': getFakeList,
};
那我们转进 mock/api.js
就可以看到 JSON 内容的生成了。
在开发环境中,前后端开发服务器常常部署在 localhost 的不同端口,这个问题常常困扰前后端分离范式的开发者。但有了 roadhog 之后,对上述的 .roadhogrc.mock.js
稍做修改就可以在前端的开发服务器上“构建”一个本地反代,轻松避免这个问题。
本地开发中的跨域问题
大多数浏览器要求 fetch 通过 HTTPS 进行,但对 localhost 有本地赦免,HTTP 下的 fetch 请求并不会遇到问题。(但是如果你给 localhost 做了 hosts 规则那本地开发赦免就不适用了。)
另外,对于本地,浏览器依旧强制执行 CORS 跨域检查,后端端口如果不设置
Access-Control-Allow-Origin
响应头依旧会遇到跨域安全问题。roadhog 提供的这个功能就良好解决了本地开发调试的跨域问题。
// FROM https://github.com/sorrycc/roadhog#proxy
"proxy": {
"/api": {
"target": "http://localhost:8080",
"changeOrigin": true,
"pathRewrite": { "^/api" : "" }
}
}
结语
create-react-app
预先配置了基本的工具链,让我们能很快上手纯前端的项目。而 Ant Design Pro 这个脚手架预先配置了更为完整的开发工具链,让我们能快速进行前后端交互的开发。上手的主要难点是理解庞大的工程结构,以及了解更为庞大的依赖链。
作者水平有限,如有纰漏请尽管指出。
- 关于
dva
中 Model 的概念,可以参见 Andt Design 项目实践 — 定义 Model,以及 关于dva实际应用的一些经验以及疑惑 ↩ - 关于
dva-loading
,可见 dva-loading 实践用法 ↩