原文链接12步20分钟,完成用户管理的CURD 应用(react+dva+antd),本文对原文进行了部分修改。
开始为了学习mobile-ant,但是发现推荐使用dva,因此找到了这篇文章。
本文是按照12步20分钟,完成用户管理的CURD 应用(react+dva+antd) 一步一步创建一个CURD 应用,包含查询、编辑、删除、创建,以及分页处理,数据mock,自动处理loading 状态等,基于react、dva 和antd。
可以通过如下方法进行学习:
- clone 本项目
1
git clone https://github.com/JobbyM/dva-example-user-dashboard.git
 - 进入项目
1
cd dva-example-user-dashboard
 - 安装依赖
1
npm install
 - 启动
1
npm start
 - 从Step 2 到Step 12 都添加了tag,所以可以通过如下方法进行学习每一步之后,运行
1
git checkout v2.0.0
就可以看到Step 2的效果了,不过Step 2 需要在浏览器中输入http://localhost:8000/#/users 才可以看到响应的效果。1
npm start
 
最终效果:
开始之前
- node 版本要求为6.5+,本地为6.10.2
 
Step 1. 安装dva-cli 并创建应用
本地安装版本为0.7.8
1  | npm i dva-cli -g  | 
然后创建应用:
1  | dva new dva-example-user-dashboard  | 
Step 2. 配置antd 和babel-plugin-import
babel-plugin-import 用于按需引入antd 的JavaScript 和CSS,这样打包出来的文件不至于太大。
1  | npm i antd --save  | 
修改.roadhogrc,在"extraBabelPlugins" 里加上:
1  | ["import", { "libraryName": "antd", "style": "css" }]  | 
注意,这里的修改是在.roadhogrc 中的"env" 中的"development" 中的"extraBabelPlugins" 中进行修改的
Step 3. 配置大力,能通过RESTFul 的方式访问 http://localhost:8000/api/users
修改.roadhogrc,加上"proxy" 配置:
1  | "proxy": {  | 
注意,这里的修改是在.roadhogrc 中的"env" 中的"development" 中进行添加的
然后启动应用:(这个命令一直开着,后面不需要重启)
1  | npm start  | 
浏览器会自动启动,并打开http://localhost:8000
访问http://localhost:8000/api/users, 就能访问到http://jsonplaceholder.typicode.com/users 的数据。(由于typicode.com 服务的稳定性,偶尔可能会失败。不过没关系,正好便于我们之后对于出错的处理)
Step 4. 生成users 路由
用 dva-cli 生成路由
1  | dva g route users  | 
然后访问http://localhost:8000/#/users
Step 5. 构造users model 和service
用dva-cli 生成Model:
1  | dva g model users  | 
修改src/models/users.js
1  | import * as usersService from '../services/users';  | 
新增src/services/users.js
1  | import request from '../utils/request';  | 
由于我们需要从respose headers 中获取total users 数量,所以需要改造下 src/utils/request.js
1  | import fetch from 'dva/fetch';  | 
切换到浏览器(会自动刷新),应该没有任何变化,因为数据虽然好了,但并没有视图与之关联。但是打开Redux 开发者工具,应该可以看到users/fetch 和users/save 的action 以及相关的state。
Step 6. 添加界面,让用户列表展现出来
用dva-cli 生成component;
1  | dva g component Users/Users  | 
然后修改生成出来的src/components/Users/Users.js 和src/components/Users/Users.css,并在src/route/Users.js 中引用他。具体参考这个Commit。
需留意两件事:
- 对model 进行了微调,加入了page 表示当前页
 - 由于components 和services 中都用到了pageSize,所以提取到了
src/constants.js 
改完后,切换浏览器,应该能看到带分页的用户列表。
Step 7. 添加layout
添加layout 布局,使得我们可以在首页和用户列表页之间来回切换。
- 添加布局,
src/components/MainLayout.js和CSS 文件 - 在
src/routes文件夹下的文件中引用这个布局 
参考这个Commit
注意:
- 页头的菜单会随着页面切换变化,高亮显示当前页所在的菜单项
 
Step 8. 通过dva-loading 处理loading 状态
dva 有一个管理effects 执行的hook,并基于此封装了dva-loading 插件。通过这个插件,我们可以不必一遍一遍写showLoading 和hideLoading,当发起请求时,插件会自动设置数据里的loading 状态为true 或false。然后我们在渲染components 时绑定并根据这个数据进行渲染。
先安装dva-loading:
1  | npm i dva-loading --save  | 
修改src/index.js 加载插件,在合适的地方加入下面两句:
1  | import createLoading from 'dva-loading';  | 
然后在src/components/Users/Users.js 里绑定loading 数据:
1  | loading: state.loading.models.users,  | 
具体参考这个Commit
切换浏览器,你的用户列表有loading 了没?
Step 9. 处理分页
只改一个文件src/components/Users/Users.js 就好。
处理分页有两个思路:
- 发起action,请求新的分页数据,保存到model,然后自动更新
 - 切换路由(由于之前监听了路由变化,所以后续的事情会自动处理)
 
我们用的是思路2 的方式,好处是用户可以直接访问到page 2 或其他页面。
参考这个Commit
Step 10. 处理用户删除
经过前面的9 步,应用的整体脉络已经清晰,相信大家已经对整体流程也有了一定了解。
后面的功能调整都可以按照以下三步进行:
- services
 - model
 - component
 
我们现在开始增加用户删除功能。
service,修改
src/services/users.js1
2
3
4
5export function remove(id) {
return request(`/api/users/${id}`, {
method: 'DELETE',
});
}model,修改
src/models/users.js1
2
3
4
5*remove({ payload: id }, { call, put, select }) {
yield call(usersService.remove, id);
const page = yield select(state => state.users.page);
yield put({ type: 'fetch', payload: { page } });
},component,修改
src/components/Users.js,替换deleteHandler内容:1
2
3
4dispatch({
type: 'users/remove',
payload: id,
});
Step 11. 处理用户编辑
处理用户编辑和前面的一样,遵循三步走:
- services
 - model
 - component
 
先是service,修改src/services/users.js:
1  | export function patch(id, values) {  | 
再是model,修改src/models/users.js:
1  | *patch({ payload: { id, values } }, { call, put, select }) {  | 
最后是component,详见Commit。
需要注意的一点是,我们在这里如何处理Modal 的visible 状态,有几种选择:
- 存dva 的model state 里
 - 存component state 里
 
另外,怎么存也是个问题,可以:
- 只有一个visible,然后根据用户点选的user 填不同的表单数据
 - 几个user 几个visible
 
此教程选的方案是202,即存component state,并且visible 按user 存。另外为了使用的简便,封装了一个UserModal 的组件。
完成后,切换到浏览器,应该就能够对用户进行编辑了。
Step 12. 处理用户创建
先比用户编辑,用户创建更简单些,因为可以共用UserModal 组件。和Step 11 比较类似,就不赘述了,详见Commit
到这里,我们已经完成了一个完整的CURD 应用。但仅仅是完成,并不完善,比如:
- 如何处理错误,比如请求等
 - 如何处理请求超时
 - 如果根据路由动态加载JS 和CSS
 - …
 
请期待下一篇。