原文链接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.js
1
2
3
4
5export function remove(id) {
return request(`/api/users/${id}`, {
method: 'DELETE',
});
}model,修改
src/models/users.js
1
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
- …
请期待下一篇。