0%

Ant Design Pro 使用

Ant Design Pro 是蚂蚁金服团队在 Ant Design 的设计规范与组件库基础上推出的一套 React 实现的企业级中后台前端/设计解决方案

安装

方式一:直接 clone git 仓库

1
2
$ git clone --depth=1 https://github.com/ant-design/ant-design-pro.git my-project
$ cd my-project

方式二:使用npm命令行工具

1
2
3
$ npm install ant-design-pro-cli -g
$ mkdir my-project && cd my-project
$ pro new # 安装脚手架

目录结构

我们已经为你生成了一个完整的开发框架,提供了涵盖中后台开发的各类功能和坑位,下面是整个项目的目录结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
├── mock                     # 本地模拟数据
├── public
│   └── favicon.ico # Favicon
├── src
│   ├── assets # 本地静态资源
│   ├── common # 应用公用配置,如导航信息
│   ├── components # 业务通用组件
│   ├── e2e # 集成测试用例
│   ├── layouts # 通用布局
│   ├── models # dva model
│   ├── routes # 业务页面入口和常用模板
│   ├── services # 后台接口服务
│   ├── utils # 工具库
│   ├── g2.js # 可视化图形配置
│   ├── theme.js # 主题配置
│   ├── index.ejs # HTML 入口模板
│   ├── index.js # 应用入口
│   ├── index.less # 全局样式
│   └── router.js # 路由入口
├── tests # 测试工具
├── README.md
└── package.json

本地开发

安装依赖。

1
$ npm install

如果网络状况不佳,可以使用

1
$ cnpm install

启动完成后会自动打开浏览器访问 http://localhost:8000,你看到下面的页面就代表成功了。

首页截图

加页面

新建菜单栏标签

在\src\common\menu.js中加入我们的新标签。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
name: 'dashboard',
icon: 'dashboard',
path: 'dashboard',
children: [
{
name: '分析页',
path: 'analysis',
},
{
name: '监控页',
path: 'monitor',
},
{
name: '工作台',
path: 'workplace',
// hideInBreadcrumb: true,
// hideInMenu: true,
},
{
name: '测试页',
path: 'test',
},
],
},

新建页面

在src/routes 下新建 pages文件夹,里面再新建页面。newPage.js

1
2
3
4
5
6
7
8
9
10
11
12
13
import React,{PureComponent} from 'react';


export default class Workplace extends PureComponent{
render(){
return(
<view>
<h1>Hello World</h1>
</view>
)
}
}

新建该页面的路由

在\src\common\router.js的getRouterData中加入我们的页面。

1
2
3
4
5
6
7
8
9
10
11
12
'/': {
component: dynamicWrapper(app, ['user', 'login'], () => import('../layouts/BasicLayout')),
},
'/dashboard/analysis': {
component: dynamicWrapper(app, ['chart'], () => import('../routes/Dashboard/Analysis')),
},
'/dashboard/monitor': {
component: dynamicWrapper(app, ['monitor'], () => import('../routes/Dashboard/Monitor')),
},
'/dashboard/test': {
component: dynamicWrapper(app, [], () => import('../routes/pages/newPage')),
},

至此,我们的页面已经可以展示了。

组件化模块

实际使用时如果控件重复我们可以写到组件里调用

新建组件

如下:
在src/components下新建一个 大写的文件夹名ImageWrapper,里面新建文件index.js index.less
index.js

1
2
3
4
5
6
7
8
9
import React from 'react'
import styles from './index.less'

export default ({src,desc,style})=>(
<div styles={style} className={styles.imageWrapper}>
<img src={src} alt="desc" className={styles.img}/>
{desc && <div className={styles.desc}>{desc}</div>}
</div>
);

index.less

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.imageWrapper {
padding: 0 20px 8px;
background: #f2f4f5;
width: 400px;
margin: 0 auto;
text-align: center;
}

.img {
vertical-align: middle;
max-width: calc(100% - 32px);
margin: 2.4em 1em;
box-shadow: 0 8px 20px rgba(143, 168, 191, 0.35);
}

调用组件

在我之前新建的newPage.js中调用我们的组件

1
2
3
4
5
6
7
8
9
10
11
12
13
import React,{PureComponent} from 'react';
import ImageWrapper from '../../components/ImageWrapper'

export default class Workplace extends PureComponent{

render(){
return(
<view>
<ImageWrapper src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1523969861626&di=514baab40d332e00c2eee8a5717a652a&imgtype=0&src=http%3A%2F%2Ftv06.tgbusdata.cn%2Fv2%2Fthumb%2Fjpg%2FMDA5QSw1ODAsMTAwLDQsMywxLC0xLDAscms1MA%3D%3D%2Fu%2Fwow.tgbus.com%2FUploadFiles_2396%2F201206%2F2012060410191894.jpg" desc="测试数据"></ImageWrapper>
</view>
)
}
}

好了,调用正常吧。

数据交互

Ant Design Pro 是一套基于 React 技术栈的单页面应用,提供的是前端代码和本地模拟数据的开发模式,
通过 Restful API 的形式和任何技术栈的服务端应用一起工作。

前端请求流程

在 Ant Design Pro 中,一个完整的前端 UI 交互到服务端处理流程是这样的:

  1. UI 组件交互操作;
  2. 调用 model 的 effect;
  3. 调用统一管理的 service 请求函数;
  4. 使用封装的 request.js 发送请求;
  5. 获取服务端返回;
  6. 然后调用 reducer 改变 state;
  7. 更新 model。

从上面的流程可以看出,为了方便管理维护,统一的请求处理都放在 services 文件夹中,并且一般按照 model 维度进行拆分文件,如:

1
2
3
4
services/
user.js
api.js
...

其中,utils/request.js 是基于 fetch 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。具体可以参看 request.js

Ant Design Pro 直接沿用了 roadhog 中自带的 mock 功能,方便本地快速开发调试。
还是以之前的测试页面为例,我们为它新建一个测试请求:

新建一个dva model

在src/models 新建文件testdata.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { queryProjectList} from '../services/api';

export default {
namespace: 'testdata',

state: {
testdata:{},
},

effects: {
*fetchProject(_, { call, put }) {
const response = yield call(queryProjectList);
yield put({
type: 'saveProject',
payload: response,
});
},
},

reducers: {
saveProject(state, action) {
return {
...state,
testdata: action.payload,
};
},
},
};

其中queryProjectList是我们真正要发的请求方法

新建请求方法

在src/services/api.js中新建方法:

1
2
3
export async function queryProjectList() {
return request('/api/project');
}

request(‘/api/project’);就是实际的请求路径,是在本地调试代理下,所以请求最终会被mock到.roadhogrc.mock.js

新建测试请求数据

在.roadhogrc.mock.js中新建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'GET /api/project' : {
code: 0,
content: [
{
"create_time": "Tue, 12 Dec 2017 11:27:40 GMT",
"create_user": "test1",
"entry": 6,
"project_key": "test1_app"
},
{
"create_time": "Tue, 12 Dec 2017 11:28:00 GMT",
"create_user": "test2",
"entry": 7,
"project_key": "test2_app"
}
]
}

页面发请求

回到 之前新建的newPage.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import React,{PureComponent} from 'react';
import ImageWrapper from '../../components/ImageWrapper'
import { connect } from 'dva';

@connect(({ testdata,loading }) => ({
testdata,
loading: loading.effects['project/fetchProject'],
}))

export default class Workplace extends PureComponent{
componentDidMount() {
const { dispatch } = this.props;
dispatch({
type: 'testdata/fetchProject',
});
}
render(){
const { testdata,loading } = this.props;
return(
<view>
<ImageWrapper src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1523969861626&di=514baab40d332e00c2eee8a5717a652a&imgtype=0&src=http%3A%2F%2Ftv06.tgbusdata.cn%2Fv2%2Fthumb%2Fjpg%2FMDA5QSw1ODAsMTAwLDQsMywxLC0xLDAscms1MA%3D%3D%2Fu%2Fwow.tgbus.com%2FUploadFiles_2396%2F201206%2F2012060410191894.jpg" desc="测试数据"></ImageWrapper>
<p>{testdata.testdata.content[0].create_user}</p>
</view>
)
}
}

@connect 装饰器
首先的组件写法中调用了 dva 所封装的 react-redux 的 @connect 装饰器,用来接收绑定的 list 这个 model 对应的 redux store。注意到这里的装饰器实际除了 app.state.testdata以外还实际接收 app.state.loading 作为参数,这个 loading 的来源是 src/index.js 中调用的 dva-loading 2 这个插件。它返回的信息包含了 global、model 和 effect 的异步加载完成情况。