综述
dva
是一个基于redux
和redux-saga
的数据流方案,dva
还额外内置了react-router
和fetch
,因此是一个轻量级的应用框架.
特性
- 易学易用,仅有6个API,对redux用户非常友好。
- elm概念,通过reducers,effects和subscriptions组织model。
- 插件机制,例如dva-loading可以自动处理loading状态,不用一遍遍地写showLoading和hideLoading。
- 支持HMR,基于babel-plugin-dva-hmr实现components,routes和models的HMR
快速开始
- 安装dva-cli「打开终端,使用npm安装dva-cli并确保版本是0.9.1或以上」
$ npm install dva-cli -g
$ dva -v
dva-cli version 0.91
- 创建新应用
- 安装完dva-cli后,就可以在命令行中访问到dva命令
- 现在 通过
dva new
创建新 App
$ dva new dva-quickstart
- 「注释」这个命令会创建
dva-quickstart
目录,包含项目初始化目录和文件,并提供开发服务器、构建脚本、数据mock服务、代理服务器等功能。 - 使用如下命令来启动服务器「要在该项目目录下」:
$ npm start
(等待一段时间后,你会看到以下输出:)
Compiled successfully!
The app is running at:
http://localhost:8000/
Note that the development build is not optimized.
To create a production build, use npm run build.
(在浏览器中打开http://localhost:8000,可以看到dva的欢迎界面)
- 使用antd
- 通过npm 安装
antd
和babel-plugin-import
。后者是用来按需加载antd的脚本和样式的。
- 通过npm 安装
$ npm install antd babel-plugin-import --save
- 定义路由
- 第一步:创建路由,路由可以想象成是组成应用的不同页面。
- 新建route component
routes/Products.js
,如下:
- 新建route component
- 第一步:创建路由,路由可以想象成是组成应用的不同页面。
import React from 'react';
const Products = (props) => (
<h2>List of Products</h2>
);
export default Products;
- 添加路由信息到路由表,编辑
router.js
import Products from './routes/Products';
...
<Route path="/products" exact component={Products} />
-
然后在浏览器里打开 http://localhost:8000/#/products ,你应该能看到前面定义的
标签
-
编写UI Component
- 多个页面共享一个元素(或一个UI元素在一个页面中被使用多次),在DVA中可以将这部分抽成component
- 编写一个
ProductList
component,这样就可以在不同的地方显示产品列表「新建components/Producct.js
」
import React from 'react';
import PropTypes from 'prop-types';
import {Table, Popconfirm, Button} from 'antd';
const ProductList = ({ onDelete, products }) =>{
const columns = [{
title:'Name',
dataIndex:'name',
},{
title:'Actions',
render: (text, record) => {
return (
<Popconfirm title="Delete?" onConfirm={() => onDelete(record.id)}>
<Button>Delete</Button>
</Popconfirm>
);
},
}];
return (
<Table
dataSource={products}
columns={columns}
/>
);
};
ProductList.proptype = {
onDelete:PropTypes.func.isRequired,
products:PropTypes.array.isrequired,
};
export default ProductList;
- 定义Model
- 完成UI后,现在开始处理数据和逻辑
- dva通过model的概念把一个领域的模型管理起来,包含同步更新state的reducer 是,处理异步逻辑的effects,订阅数据源的subscriptions。
// models/products.js
export default{
namespace: 'products', //表示在全局state上的key
state:[], //初始值,在这里是空数组
reducers:{ //redux里的reducer,接收action,同步更新state
'delete'(state, {payload: id }) {
return state.filter(item => item.id !== id);
},
},
};
- 然后在
index.js
里载入models/products.js
app.model(require('./models/products').default);
- connect
- 到处,我们已经完成了model和component,使用dva提供的
connect
方法,若你熟悉redux
,这个connect就是react-redux
中的connect,编辑routes/products.js
- 到处,我们已经完成了model和component,使用dva提供的
import React from 'react';
import { connect } from 'dva';
import ProductList from '../compponents/ProductList';
const Products = ({ dispatch, products }) =>{
function handleDelete(id){
dispatch({
type:'products/delete',
payload:id,
});
}
return(
<div>
<h2>List of Products</h2>
<ProductList onDelete={handleDelete} products={products} />
</div>
);
};
// export default Products;
export default connect(({ products }) => ({
products,
}))(Products);