文章目录

  • 前言:
  • 第一步:
  • 第二步,
  • 第三步,
  • 第四步,
  • 第五步,
  • 第六步,
  • 第七步,
  • 第八步,
  • 第九步,
  • 第10步,

个人博客


前言:

原谅我直接跳过react的基础,直接就讲react+dva的实际应用,因为直接从项目结构来讲,我觉得学习的成本更低,开发的速度更快,当然有时间的话还是建议冲react的基础学起。

react的参考资料:
建议先从React 入门实例教程开始学
react的全家桶系列也不错

dva的参考资料:
dva的官方指南有很多不错的脚手架
ant design组合ant design UI可以说非常方便

例子
实现效果

前提条件

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

第一步:

打开cmd,切换到你要安装的目录,使用npm安装dva-cli

$ npm i dva-cli@0.7 -g
$ dva -v
0.7.0

然后可以在命令行输入命令创建应用

$ dva new user-dashboard
$ cd user-dashboard 

第二步,

配置 antd 和 babel-plugin-import
babel-plugin-import 主要是用于按需引入 antd 的 JavaScript 和 CSS,这样打包出来的文件不至于太大。详情请看dva

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

如果dva的版本是在0.7一下的话是没有.roadhogrc文件,修改 .roadhogrc,在 “extraBabelPlugins” 里加上,0.7一下的话是修改.webpackrc文件:

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

第三步,

配置代理,能通过 RESTFul 的方式访问
修改 .roadhogrc,加上 “proxy” 配置,或者修改.webpackrc文件也可:
可以通过http://localhost:8000/api/users来查看json数据

"proxy": {"/api": {"target": "http://jsonplaceholder.typicode.com/","changeOrigin": true,"pathRewrite": { "^/api" : "" }}
},

然后启动应用:可以新开一个命令行窗口

$ npm start

然后系统就会自动在浏览器中打开页面,也可以访问http://localhost:8000/

第四步,

生成 users 路由

dva g route users

输入这个命令就会在src的routes生成两个文件,一个User.js,一个是User.css,然后访问 http://localhost:8000/#/users 。

第五步,

构造 users model 和 service
同上,用dva的命令生成文件

dva g model users

然后修改 src/models/users.js :

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:

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:

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

第六步,

添加界面,让用户列表展现出来
用 dva-cli 生成 component:

$ dva g component Users/Users

然后修改生成出来的 src/components/Users/Users.js 和 src/components/Users/Users.css,并在 src/routes/Users.js 中引用他。
User.js

import React from 'react';
import { connect } from 'dva';
import { Table, Pagination, Popconfirm, Button } from 'antd';
import { routerRedux } from 'dva/router';
import styles from './Users.css';
import { PAGE_SIZE } from '../../constants';
import UserModal from './UserModal';function Users({ dispatch, list: dataSource, loading, total, page: current }) {function deleteHandler(id) {dispatch({type: 'users/remove',payload: id,});}function editHandler(id, values) {dispatch({type: 'users/patch',payload: { id, values },});}function pageChangeHandler(page) {dispatch(routerRedux.push({pathname: '/users',query: { page },}));}function createHandler(values) {dispatch({type: 'users/create',payload: values,});}const columns = [{title: '姓名',dataIndex: 'name',key: 'name',render: text => <a href="">{text}</a>,},{title: '邮箱',dataIndex: 'email',key: 'email',},{title: '地址',dataIndex: 'website',key: 'website',},{title: '操作',key: 'operation',render: (text, record) => (<span className={styles.operation}><UserModal record={record} onOk={editHandler.bind(null, record.id)}><a>修改</a></UserModal><Popconfirm title="Confirm to delete?" onConfirm={deleteHandler.bind(null, record.id)}><a href="">删除</a></Popconfirm></span>),},];return (<div className={styles.normal}><div><div className={styles.create}><UserModal record={{}} onOk={createHandler}><Button type="primary">增加用户</Button></UserModal></div><Tablecolumns={columns}dataSource={dataSource}loading={loading}rowKey={record => record.id}pagination={false}/><PaginationclassName="ant-table-pagination"total={total}current={current}pageSize={PAGE_SIZE}onChange={pageChangeHandler}/></div></div>);
}function mapStateToProps(state) {const { list, total, page } = state.users;return {loading: state.loading.models.users,list,total,page,};
}export default connect(mapStateToProps)(Users);

User.css

.normal {
}
.create {margin-bottom: 1.5em;
}.operation a {margin: 0 .5em;
}

这边主要是对 model 进行了微调,加入了 page 表示当前页
由于 components 和 services 中都用到了 pageSize,所以提取到 src/constants.js
改完后,切换到浏览器,应该能看到带分页的用户列表

第七步,

添加 layout

  1. 添加 layout 布局,使得我们可以在首页和用户列表页之间来回切换。
    2.添加布局,src/components/MainLayout/MainLayout.js 和 CSS 文件
    在 src/routes 文件夹下的文件中引用这个布局
import React from 'react';
import { Router, Route } from 'dva/router';
import IndexPage from './routes/IndexPage';import Users from "./routes/Users.js";function RouterConfig({ history }) {return (<Router history={history}><Route path="/" component={IndexPage} /><Route path="/users" component={Users} /></Router>);
}export default RouterConfig;

第八步,

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

先安装 dva-loading :

npm i dva-loading --save

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

import createLoading from 'dva-loading';
app.use(createLoading());

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

loading: state.loading.models.users,

具体参考这个 例子。

第九步,

处理分页
只改一个文件 src/components/Users/Users.js 就好。

处理分页有两个思路:

  1. 发 action,请求新的分页数据,保存到 model,然后自动更新页面
  2. 切换路由 (由于之前监听了路由变化,所以后续的事情会自动处理)
    我们用的是思路 2 的方式,好处是用户可以直接访问到 page 2 或其他页面。

参考这个 例子。

第10步,

用户的修改,删除,增加都是对三个文件的操作

  1. service, 修改 src/services/users.js:
import request from '../utils/request';
import { PAGE_SIZE } from '../constants';export function fetch({ page }) {return request(`/api/users?_page=${page}&_limit=${PAGE_SIZE}`);}//删除
export function remove(id) {return request(`/api/users/${id}`, {method: 'DELETE',});
}
//修改
export function patch(id, values) {return request(`/api/users/${id}`, {method: 'PATCH',body: JSON.stringify(values),headers: {'Content-Type': 'application/json','Accept': 'application/json',},});
}
//新增
export function create(values) {return request('/api/users', {method: 'POST',body: JSON.stringify(values),});}
  1. model, 修改 src/models/users.js:
import * as usersService from '../services/users';export default {namespace: 'users',state: {list: [],total: null,page: null,},reducers: {save(state, { payload: { data: list, total, page } }) {return { ...state, list, total, page };},},effects: {//分页*fetch({ payload: { page = 1 } }, { call, put }) {const { data, headers } = yield call(usersService.fetch, { page });yield put({type: 'save',payload: {data,total: parseInt(headers['x-total-count'], 10),page: parseInt(page, 10),},});},//删除*remove({ payload: id }, { call, put }) {yield call(usersService.remove, id);yield put({ type: 'reload' });},//修改
*patch({ payload: { id, values } }, { call, put }) {yield call(usersService.patch, id, values);yield put({ type: 'reload' });
},
//新增
*create({ payload: values }, { call, put }) {yield call(usersService.create, values);yield put({ type: 'reload' });},*reload(action, { put, select }) {const page = yield select(state => state.users.page);yield put({ type: 'fetch', payload: { page } });},},subscriptions: {setup({ dispatch, history }) {return history.listen(({ pathname, query }) => {if (pathname === '/users') {dispatch({ type: 'fetch', payload: query });}});},},
};
  1. component, 修改 src/components/Users/Users.js,替换 deleteHandler 内容:
import React from 'react';
import { connect } from 'dva';
import { Table, Pagination, Popconfirm, Button } from 'antd';
import { routerRedux } from 'dva/router';
import styles from './Users.css';
import { PAGE_SIZE } from '../../constants';
import UserModal from './UserModal';function Users({ dispatch, list: dataSource, loading, total, page: current }) {
//删除function deleteHandler(id) {dispatch({type: 'users/remove',payload: id,});}
//修改function editHandler(id, values) {dispatch({type: 'users/patch',payload: { id, values },});}
//分页function pageChangeHandler(page) {dispatch(routerRedux.push({pathname: '/users',query: { page },}));}
//新增function createHandler(values) {dispatch({type: 'users/create',payload: values,});}const columns = [{title: '姓名',dataIndex: 'name',key: 'name',render: text => <a href="">{text}</a>,},{title: '邮箱',dataIndex: 'email',key: 'email',},{title: '地址',dataIndex: 'website',key: 'website',},{title: '操作',key: 'operation',render: (text, record) => (<span className={styles.operation}><UserModal record={record} onOk={editHandler.bind(null, record.id)}><a>修改</a></UserModal><Popconfirm title="Confirm to delete?" onConfirm={deleteHandler.bind(null, record.id)}><a href="">删除</a></Popconfirm></span>),},];return (<div className={styles.normal}><div><div className={styles.create}><UserModal record={{}} onOk={createHandler}><Button type="primary">增加用户</Button></UserModal></div><Tablecolumns={columns}dataSource={dataSource}loading={loading}rowKey={record => record.id}pagination={false}/><PaginationclassName="ant-table-pagination"total={total}current={current}pageSize={PAGE_SIZE}onChange={pageChangeHandler}/></div></div>);
}function mapStateToProps(state) {const { list, total, page } = state.users;return {loading: state.loading.models.users,list,total,page,};
}export default connect(mapStateToProps)(Users);

以上就是react+dva+antd实现的一个简单的增删改的操作例子。

react+dva+antd的骚操作相关推荐

  1. React+dva+antd的运用

    前言 技术资料 react + dva + redux + react-router + redux-sage + antd + antd动画 总的来说dva是一个很简单的项目 一步步跟大家来说一下把 ...

  2. react+dva+antd接口调用方式

    一丶 安装 通过 npm 安装 dva-cli 并确保版本是0.8.1或以上. $ npm install dva-cli -g $ dva -v 0.8.1 二丶创建新应用 安装完dva-cli之后 ...

  3. antd 进行ajax请求,react+dva+antd接口调用方式

    一丶 安装 通过 npm 安装 dva-cli 并确保版本是0.8.1或以上. $ npm install dva-cli -g $ dva -v 0.8.1 二丶创建新应用 安装完dva-cli之后 ...

  4. antd 怎么用ajax,react+dva+antd接口调用方式

    一丶 安装 通过 npm 安装 dva-cli 并确保版本是0.8.1或以上.$ npm install dva-cli -g $ dva -v0.8.1 二丶创建新应用 安装完dva-cli之后,就 ...

  5. React+DVA开发实践

    原文链接 文档概述 本文档在前面章节简单的介绍了React和其相关的一系列技术,最后章节介绍了React+Dva开发的整套过程和基本原理,也就是将一系列框架整合的结果. 文档结构 本文档划分为以下章节 ...

  6. 【单页面博客从前端到后端】基于 DVA+ANTD 搭建博客前后台界面

    在上篇文章我们已经搭建好了基础的开发环境,接下来会介绍如何引入 DVA 和 ANTD ,以及在引入过程中需要注意的问题.这里只会详细的书写部分组件,其他的组件都是大同小异.你可以在 github仓库 ...

  7. 骚操作!有了这款神器,轻轻松松用Python写APP!(文末彩蛋)

    本文转自机器之心  作者:Adrien Treuille 机器之心编译 参与:魔王.一鸣 机器学习开发者想要打造一款 App 有多难?事实上,你只需要会 Python 代码就可以了,剩下的工作都可以交 ...

  8. 数据库的 N 多骚操作了解一下?

    作者 | zone7 责编 | 郭   芮 本文来介绍一下 Python 与 MongoDB 数据库的使用,走起! MongoDB GUI 工具 首先介绍一款 MongoDB 的 GUI 工具 Rob ...

  9. react:react + dva + router + roadhog 基础项目搭建

    一.脚手架安装 第一步:全局安装 dva,这里有个条件,node 版本要 >= 6.5 且 dva-cli 版本要在 0.7x. npm install dva-cli -g 第二步:查看版本号 ...

最新文章

  1. 【Latext】上标下标 ( 右侧上标下标 | 任意字符的正上标记 | 任意字符的正下标记 | 常用数学符号的上标和下标 | 加和 | 乘积 | 交集 | 并集 | 上积 | 极限 | 上弧 )
  2. 为什么Map桶中个数超过8才转为红黑树
  3. 【iMX6ULL】触觉 imx6ull开发板交叉编译环境搭建
  4. Ubuntu开启telnet服务
  5. Linux命令之stty
  6. webpack中library和libraryTarget详解
  7. C++模版类List实现
  8. [nowcoder]最长区间
  9. 论文阅读笔记——人脸网络:人脸识别和聚类的统一嵌入
  10. 餐饮水单打印软件_介绍送货单打印软件模板样式之购物小票格式
  11. 遗传算法解决车辆路径问题
  12. 【毕业论文】分享当年使用过的一些好用网站,包括论文去重,翻译,作图神器,免费文献查找 | 第 1 期
  13. 360校招笔试题总结4
  14. Unity3d模型渲染灯光黑暗问题解决
  15. mysql安装到吐血
  16. iib mq 在linux环境下安装
  17. 数据预处理利器 Amazon Glue DataBrew
  18. 现在手机千篇一律,下一个乔布斯的传奇在哪?
  19. 为什么一边裁员,一边招人。。
  20. centos6.10 mysql 5.7_如何在CentOS6.10安装MySQL5.7

热门文章

  1. 关于工作 关于爱情婚姻
  2. oracle11g正则表达式
  3. Excel 中对2列数据进行“或”筛选
  4. linux内核patch文件夹,如何制作patch文件及如何打patch 附带linux打补丁命令
  5. react axios配置代理(proxy),解决本地开发时的跨域问题
  6. 中国这门失传已久的武林绝学,竟让研究它的老外拿了诺贝尔奖
  7. 原始LSH算法实现详解
  8. 【一】数据挖掘(DM)到底是何方神圣?
  9. C++大战Python - 以C++11重写欢乐斗地主残局解答器
  10. Arnold Htoa 直接调用Houdini海洋频谱做置换