文档章节

【转】基于 (react+dva+antd)完成用户管理的 CURD 应用,升级版antd-admin

wlc534
 wlc534
发布于 2017/09/12 10:36
字数 1777
阅读 179
收藏 2
点赞 0
评论 0

本文会一步步引导大家如何创建一个 CURD 应用,包含查询、编辑、删除、创建,以及分页处理,数据 mock,自动处理 loading 状态等,基于 react, dva 和 antd 。

最终效果:

开始之前:

  • 确保 node 版本是 6.5 +
  • 用 cnpm 或 yarn 能节约你安装依赖的时间

Step 1. 安装 dva-cli 并创建应用

先安装 dva-cli,并确保版本是 0.7 或以上。

Shell

 

1

2

3

$ npm i dva-cli -g

$ dva -v

0.7.0

然后创建应用:

Shell

 

1

2

$ dva new user-dashboard

$ cd user-dashboard

 

Step 2. 配置 antd 和 babel-plugin-import

babel-plugin-import 用于按需引入 antd 的 JavaScript 和 CSS,这样打包出来的文件不至于太大。

Shell

 

1

2

$ npm i antd --save

$ npm i babel-plugin-import --save-dev

修改 .roadhogrc,在 "extraBabelPlugins" 里加上:

JavaScript

 

1

["import", { "libraryName": "antd", "style": "css" }]

 

Step 3. 配置代理,能通过 RESTFul 的方式访问http://localhost:8000/api/users

修改 .roadhogrc,加上 "proxy" 配置:

JavaScript

 

1

2

3

4

5

6

7

"proxy": {

  "/api": {

    "target": "http://jsonplaceholder.typicode.com/",

    "changeOrigin": true,

    "pathRewrite": { "^/api" : "" }

  }

},

然后启动应用:(这个命令一直开着,后面不需要重启)

Shell

 

1

$ npm start

浏览器会自动开启,并打开 http://localhost:8000 。

访问 http://localhost:8000/api/users ,就能访问到 http://jsonplaceholder.typicode.com/users 的数据。(由于 typicode.com 服务的稳定性,偶尔可能会失败。不过没关系,正好便于我们之后对于出错的处理)

68747470733a2f2f7a6f732e616c697061796f626a656374732e636f6d2f726d73706f7274616c2f6f4641504a6b78634959655a466a59415475554c2e706e67

Step 4. 生成 users 路由

用 dva-cli 生成路由:

Shell

 

1

$ dva g route users

然后访问 http://localhost:8000/#/users 。

Step 5. 构造 users model 和 service

用 dva-cli 生成 Model :

Shell

 

1

$ dva g model users

修改 src/models/users.js :

JavaScript

 

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

29

import * as usersService from '../services/users';

 

export default {

  namespace: 'users',

  state: {

    list: [],

    total: null,

  },

  reducers: {

    save(state, { payload: { data: list, total } }) {

      return { ...state, list, total };

    },

  },

  effects: {

    *fetch({ payload: { page } }, { call, put }) {

      const { data, headers } = yield call(usersService.fetch, { page });

      yield put({ type: 'save', payload: { data, total: headers['x-total-count'] } });

    },

  },

  subscriptions: {

    setup({ dispatch, history }) {

      return history.listen(({ pathname, query }) => {

        if (pathname === '/users') {

          dispatch({ type: 'fetch', payload: query });

        }

      });

    },

  },

};

新增 src/services/users.js

JavaScript

 

1

2

3

4

5

import request from '../utils/request';

 

export function fetch({ page = 1 }) {

  return request(`/api/users?_page=${page}&_limit=5`);

}

由于我们需要从 response headers 中获取 total users 数量,所以需要改造下 src/utils/request.js

JavaScript

 

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

29

30

31

32

33

34

35

36

37

import fetch from 'dva/fetch';

 

function checkStatus(response) {

  if (response.status >= 200 && response.status < 300) {

    return response;

  }

 

  const error = new Error(response.statusText);

  error.response = response;

  throw error;

}

 

/**

* Requests a URL, returning a promise.

*

* @param  {string} url       The URL we want to request

* @param  {object} [options] The options we want to pass to "fetch"

* @return {object}           An object containing either "data" or "err"

*/

export default async function request(url, options) {

  const response = await fetch(url, options);

 

  checkStatus(response);

 

  const data = await response.json();

 

  const ret = {

    data,

    headers: {},

  };

 

  if (response.headers.get('x-total-count')) {

    ret.headers['x-total-count'] = response.headers.get('x-total-count');

  }

 

  return ret;

}

切换到浏览器(会自动刷新),应该没任何变化,因为数据虽然好了,但并没有视图与之关联。但是打开 Redux 开发者工具,应该可以看到 users/fetch 和 users/save 的 action 以及相关的 state 。

68747470733a2f2f7a6f732e616c697061796f626a656374732e636f6d2f726d73706f7274616c2f44744e6f586a5141644d534a717a4f53455a416f2e706e67

Step 6. 添加界面,让用户列表展现出来

用 dva-cli 生成 component:

Shell

 

1

$ dva g component Users/Users

然后修改生成出来的 src/components/Users/Users.js 和 src/components/Users/Users.css,并在src/routes/Users.js 中引用他。具体参考这个 Commit

需留意两件事:

  1. 对 model 进行了微调,加入了 page 表示当前页
  2. 由于 components 和 services 中都用到了 pageSize,所以提取到 src/constants.js

改完后,切换到浏览器,应该能看到带分页的用户列表。

68747470733a2f2f7a6f732e616c697061796f626a656374732e636f6d2f726d73706f7274616c2f6763456c70527054446b7055456d72585247486e2e706e67

Step 7. 添加 layout

添加 layout 布局,使得我们可以在首页和用户列表页之间来回切换。

  1. 添加布局,src/components/MainLayout/MainLayout.js 和 CSS 文件
  2. 在 src/routes 文件夹下的文件中引用这个布局

参考这个 Commit

注意:

  1. 页头的菜单会随着页面切换变化,高亮显示当前页所在的菜单项

Step 8. 通过 dva-loading 处理 loading 状态

dva 有一个管理 effects 执行的 hook,并基于此封装了 dva-loading 插件。通过这个插件,我们可以不必一遍遍地写 showLoading 和 hideLoading,当发起请求时,插件会自动设置数据里的 loading 状态为 true 或 false 。然后我们在渲染 components 时绑定并根据这个数据进行渲染。

先安装 dva-loading :

Shell

 

1

$ npm i dva-loading --save

修改 src/index.js 加载插件,在合适的地方加入下面两句:

JavaScript

 

1

2

+ import createLoading from 'dva-loading';

+ app.use(createLoading());

然后在 src/components/Users/Users.js 里绑定 loading 数据:

JavaScript

 

1

+ loading: state.loading.models.users,

具体参考这个 Commit 。

切换到浏览器,你的用户列表有 loading 了没?

Step 9. 处理分页

只改一个文件 src/components/Users/Users.js 就好。

处理分页有两个思路:

  1. 发 action,请求新的分页数据,保存到 model,然后自动更新页面
  2. 切换路由 (由于之前监听了路由变化,所以后续的事情会自动处理)

我们用的是思路 2 的方式,好处是用户可以直接访问到 page 2 或其他页面。

参考这个 Commit 。

Step 10. 处理用户删除

经过前面的 9 步,应用的整体脉络已经清晰,相信大家已经对整体流程也有了一定了解。

后面的功能调整基本都可以按照以下三步进行:

  1. service
  2. model
  3. component

我们现在开始增加用户删除功能。

  1. service, 修改 src/services/users.js

    JavaScript

     

    1

    2

    3

    4

    5

    export function remove(id) {

      return request(`/api/users/${id}`, {

        method: 'DELETE',

      });

    }

  1. model, 修改 src/models/users.js

    JavaScript

     

    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 } });

    },

  1. component, 修改 src/components/Users/Users.js,替换 deleteHandler 内容:

    JavaScript

     

    1

    2

    3

    4

    dispatch({

      type: 'users/remove',

      payload: id,

    });

切换到浏览器,删除功能应该已经生效。

Step 11. 处理用户编辑

处理用户编辑和前面的一样,遵循三步走:

  1. service
  2. model
  3. component

先是 service,修改 src/services/users.js

JavaScript

 

1

2

3

4

5

6

export function patch(id, values) {

  return request(`/api/users/${id}`, {

    method: 'PATCH',

    body: JSON.stringify(values),

  });

}

再是 model,修改 src/models/users.js

JavaScript

 

1

2

3

4

5

*patch({ payload: { id, values } }, { call, put, select }) {

  yield call(usersService.patch, id, values);

  const page = yield select(state => state.users.page);

  yield put({ type: 'fetch', payload: { page } });

},

最后是 component,详见 Commit

需要注意的一点是,我们在这里如何处理 Model 的 visible 状态,有几种选择:

  1. 存 dva 的 model state 里
  2. 存 component state 里

另外,怎么存也是个问题,可以:

  1. 只有一个 visible,然后根据用户点选的 user 填不同的表单数据
  2. 几个 user 几个 visible

此教程选的方案是 2-2,即存 component state,并且 visible 按 user 存。另外为了使用的简便,封装了一个UserModal 的组件。

完成后,切换到浏览器,应该就能对用户进行编辑了。

Step 12. 处理用户创建

相比用户编辑,用户创建更简单些,因为可以共用 UserModal 组件。和 Step 11 比较类似,就不累述了,详见 Commit 。

到这里,我们已经完成了一个完整的 CURD 应用。但仅仅是完成,并不完善,比如:

  • 如何处理错误,比如请求等
  • 如何处理请求超时
  • 如何根据路由动态加载 JS 和 CSS

请期待下一篇。

(完)

© 著作权归作者所有

共有 人打赏支持
wlc534
粉丝 4
博文 30
码字总数 30966
作品 0
IDEMaker/IDEMaker-php开源订餐系统

IDEMaker开源订餐系统 IDEMaker开源订餐系统是-B2B2C商业化的开源项目平台 MVC设计架构模式,基于php+mysql的外卖订餐网站,包括前端,后台,商家后台。 源码演示地址:http://dingfan.fmlyne...

IDEMaker ⋅ 2017/12/12 ⋅ 0

智能 DNS 系统 wdDNS_v3 版本正式发布

wdDNS是由wdlinux团队于2011年推出的智能DNS解析系统,基于开源软件bind开发的高效,稳定的智能DNS系统支持WEB在线管理和操作设置,支持各大运营商线路解析,分省地区路智能解析等,支持一键...

wdlinuxcn ⋅ 2017/06/26 ⋅ 7

网站内容管理系统--TXTCMS

TXTCMS 是一款基于php+smarty+txt数据库开发的网站内容管理系统,遵循MVC设计模式。本程序不依赖任何数据库,采用txt文本数据库存储方式存储数据,实现跨平台。不用数据库也能实现CURD,支持...

恶魔果实 ⋅ 2014/08/19 ⋅ 0

Kubernetes Dashboard - 每天5分钟玩转 Docker 容器技术(173)

前面章节 Kubernetes 所有的操作我们都是通过命令行工具 完成的。为了提供更丰富的用户体验,Kubernetes 还开发了一个基于 Web 的 Dashboard,用户可以用 Kubernetes Dashboard 部署容器化的...

cloudman6 ⋅ 05/27 ⋅ 0

基于 Ng-zorro-antd 的企业后台模板--ng-alain

ng-alain 一套基于 Ng-zorro-antd【ANT DESIGN】 的企业后台模板。 README in English DEMO 快速入门 确保 版本 >= 6.9.0 且 版本 >= 3 以上。 本身并非组件库,只是一个单纯的企业后台模板,...

cipchk ⋅ 2017/09/17 ⋅ 2

React构建单页应用方法与实例

React作为目前最流行的前端框架之一,其受欢迎程度不容小觑,从这门框架上我们可以学到许多其他前端框架所缺失的东西,也是其创新性所在的地方,比如虚拟DOM、JSX等。那么接下来我们就来学习...

王春-海子 ⋅ 2016/08/09 ⋅ 0

Yii 2.0开发一个仿京东商城平台

第1章 课程简介 介绍了课程内容、背景和案例展示。 第2章 项目的准备工作 介绍了如何使用PHP依赖管理工具Composer安装Yii2框架,模拟配置真实企业开发项目运行环境和编辑器。 第3章 项目前台...

15543595340 ⋅ 05/19 ⋅ 0

React性能优化

一. duplicate code 项目技术栈: view :用的是基于react的 antd + ltcrm-component。 数据流: reflux 路由: react-router 打包:atool-build 由于使用了atool-build导致无法使用webpack...

-鹏 ⋅ 2016/06/21 ⋅ 0

Web 应用开发框架--s2jh4net

简介 集结最新主流时尚开源技术的面向互联网Web应用的整合前端门户站点、HTML5移动站点及后端管理系统一体的的基础开发框架,提供一个J2EE相关主流开源技术架构整合及一些企业应用基础通用功...

xautlx ⋅ 2015/05/28 ⋅ 9

英文对照 介绍Play Framework 框架 CURD模块

CURD:管理员的生成器 h1. CRUD: Administration generator CURD(增加,读取,更新,删除)模块生成一个完全可用的web接口为你的JPA模型对象。 The CRUD (Create, Read, Update, Delete) modu...

lyuehh ⋅ 2010/08/08 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)

之前没接触过证书加密的话,对证书相关的这些概念真是感觉挺棘手的,因为一下子来了一大堆新名词,看起来像是另一个领域的东西,而不是我们所熟悉的编程领域的那些东西,起码我个人感觉如此,且很长...

颖辉小居 ⋅ 20分钟前 ⋅ 0

利用有限制通配符提升API灵活性(28)

1、参数化类型是不可变的 List<String> 不是List<Object>的子类,但是二者是有联系的 利用有限制的通配符类型处理类似情况 List<? extends Object>(生产者) Collection<? super E>(消费者......

职业搬砖20年 ⋅ 26分钟前 ⋅ 0

ssm框架 +bootstrap分页

这里有两种方式 方式一:自己写分页 方式二:使用插件PageHelper 1.自己写分页 1.1 效果 1.2 实现过程 1.2.1 创建分页公共类 //---------------------------1.属性-------------------------...

Lucky_Me ⋅ 33分钟前 ⋅ 0

Istio

helm template install/kubernetes/helm/istio --name istio --namespace istio-system > $HOME/istio.yaml after $ kubectl create namespace istio-system$ kubectl create -f $HOME/ist......

openthings ⋅ 33分钟前 ⋅ 0

内核线程、轻量级进程、用户线程

线程与进程概念 在现代操作系统中,进程支持多线程。 进程是资源管理的最小单元; 线程是程序执行的最小单元。 即线程作为调度和分配的基本单位,进程作为资源分配的基本单位 一个进程的组成...

117 ⋅ 38分钟前 ⋅ 0

elasticsearch2.4.6升级为elasticsearch-5.5.0的经历

将elasticsearch-5.5.0 中的配置 path.data 指向原来的数据路径 即 path.data: /usr/local/src/elasticsearch-2.4.6/data 注意: elasticsearch-5.5.0 需要将jdk版本升级到1.8...

晨猫 ⋅ 39分钟前 ⋅ 1

lvm讲解 磁盘故障小案例

1

oschina130111 ⋅ 43分钟前 ⋅ 0

那些提升开发人员工作效率的在线工具

本文转载自公众号 Hollis 作为一个Java开发人员,经常要和各种各样的工具打交道,除了我们常用的IDE工具以外,其实还有很多工具是我们在日常开发及学习过程中要经常使用到的。 Hollis偏爱使用...

时刻在奔跑 ⋅ 55分钟前 ⋅ 0

restful风格 实现DELETE PUT请求 的web.xml的配置

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframe......

泉天下 ⋅ 今天 ⋅ 0

Shell数组

Shell数组 Shell在编程方面比Windows批处理强大很多,无论是在循环、运算。 bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数...

蜗牛奔跑 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部