1.安裝dva-cli
npm install dva-cli -g
2.建立應用
dva new dvadashboard
[dvadashboard為專案名]
3.安裝mockjs
- npm install mockjs --save
4.配置mockjs
- 開啟.roadhogrc.mock.js 設定如下
const fs=require('fs');
const path=require('path');
const mockPath=path.join(__dirname+'/mock');
const mock={};
fs.readdirSync(mockPath).forEach(file=>{
Object.assign(mock,require('./mock/'+file));
});
module.exports=mock;複製程式碼
5.模擬使用者管理API
mock資料夾下新建user.js
API設定:
這裡只模擬倆個api 1.獲取所有使用者資料 2.新增使用者
const Mock=require('mockjs');
let db=Mock.mock({
'data|3-6':[{
id:'@id',
name:'@name',
'age|18-32':1
}]
});
module.exports={
[`GET /api/users`](req,res){
res.status(200).json(db);
},
[`POST /api/users`](req,res){
let user=req.body;
console.log(req);
user.id=Mock.mock('@id');
db.data.push(user);
res.status(200).json(user);
}
}複製程式碼
接下來看一下api能不能使用, 進入專案目錄, 執行 npm start 啟動
進入預設頁面 預設埠號 8000 如下是專案啟動後預設頁面
訪問下api http://localhost:8000/api/users 好了,可以訪問 成功返回模擬使用者列表資料
6.安裝antd
npm install antd babel-plugin-import --save
babel-plugin-import 是用來按需載入 antd 的指令碼和樣式的
安裝完成後,配置使用antd 修改.roadhogrc檔案
新增 ["import",{ "libraryName":"antd","style":"css" }] 最後檔案如下所示:
{
"entry": "src/index.js",
"env": {
"development": {
"extraBabelPlugins": [
"dva-hmr",
"transform-runtime",
["import",{ "libraryName":"antd","style":"css" }]
]
},
"production": {
"extraBabelPlugins": [
"transform-runtime",
["import",{ "libraryName":"antd","style":"css" }]
]
}
}
}複製程式碼
7.定義路由
- 在src/routes/ 資料夾下新建 usersPage.js
這可能是最簡單的一個頁面了
import { connect } from 'dva';
const UserPage=()=>{
return (
<div>
<h1>UserPage</h1>
</div>
);
};
export default connect()(UserPage);複製程式碼
- 註冊路由資訊 修改src/router.js檔案
順手加了個元件動態載入
import React from 'react';
import { Router, Route, Switch } from 'dva/router';
import dynamic from 'dva/dynamic';
import IndexPage from './routes/IndexPage';
function RouterConfig({ history,app }) {
const UserPage=dynamic({
app,
component:()=>import('./routes/usersPage')
});
return (
<Router history={history}>
<Switch>
<Route path="/" exact component={IndexPage} />
<Route path="/users" exact component={UserPage} />
</Switch>
</Router>
);
}
export default RouterConfig;複製程式碼
檢視一下路由配置效果 訪問http://localhost:8000/#/users
顯示內容了
8.新增與服務端通訊
- 修改src/utils/request.js如下 用於提供基礎的ajax資料訪問
也有不少使用axio的 具體優缺點還沒研究。
import fetch from 'dva/fetch';
const checkStatus=(response)=>{
if(response.status>=200 && response.status<=200){
return response;
}
const error=new Error(response.statusText);
error.response=response;
throw error;
};
export default async function request(url,options={}) {
options.headers={
'Content-Type':'application/json'
}
const response=await fetch(url,options);
checkStatus(response);
const data=await response.json();
return data;
}複製程式碼
這裡為了理解簡單 省略一層 user.service (封裝基礎ajax通訊 提供業務介面) 在業務層中直接呼叫request裡方法 【只是為了學習方便】
- 然後在src/models下新建user.js
import request from '../utils/request';
const User={
namespace:"user",
state:{
list:[],
visibleModal:false
},
reducers:{
save(state,{ payload:{ data:list } }){
return {
...state,
list
};
}
},
effects:{
* query({},{ call,put }){
const { data }=yield call(request,'/api/users',{ method:'GET' });
yield put({type:'save',payload:{ data }});
},
* create({ payload:{ user } },{ call,put }){
yield call(request,'/api/users',{
body:JSON.stringify(user),
method:'POST'
});
yield put({type:'query',payload:{ }});
}
},
subscriptions:{
setup({ dispatch,history }){
console.log('running subscriptions ...');
return history.listen(({ pathname,search })=>{
console.log(`pathname: ${pathname}`);
dispatch({ type:'query'});
});
}
}
};
export default User;複製程式碼
這裡主要體現dva對redux react-saga的封裝處理 一目瞭然了
- 然後註冊model 修改路由處程式碼為:
import React from 'react';
import { Router, Route, Switch } from 'dva/router';
import dynamic from 'dva/dynamic';
import IndexPage from './routes/IndexPage';
function RouterConfig({ history,app }) {
const UserPage=dynamic({
app,
models:()=>[
import('./models/user')
],
component:()=>import('./routes/usersPage')
});
return (
<Router history={history}>
<Switch>
<Route path="/" exact component={IndexPage} />
<Route path="/users" exact component={UserPage} />
</Switch>
</Router>
);
}
export default RouterConfig;複製程式碼
9.新建使用者資料列表元件 使用antd的Tabel承載
順手也把新增使用者的表單建了吧
user.js
import { Table,Button } from 'antd';
import { connect } from 'dva';
import UserModal from './create';
const UserTable = ({ list,dispatch }) => {
const createUser=(user)=>{
dispatch({
type:'user/create',
payload:{
user
}
});
};
const columns=[
{
Title:'ID',
dataIndex:'id'
},
{
Title:'NAME',
dataIndex:'name'
},
{
Title:'AGE',
dataIndex:'age'
}
];
return (
<div>
<UserModal record={ {} } ok={ createUser }>
<Button type="primary">NEW</Button>
</UserModal>
<Table
columns={ columns }
dataSource={ list }
rowKey={ t=>t.id }
pagination={ false }>
{/* users datatable */}
</Table>
</div>
);
};
export default connect(({ user }) => {
console.log(user);
return {
list: user.list
};
})(UserTable);複製程式碼
create.js
import React,{ Component } from 'react';
import { Modal,Form,Input } from 'antd';
class UserModal extends Component{
constructor(props){
super(props);
this.state={
visible:false
};
}
render(){
const { children,form:{ getFieldDecorator },record,ok }=this.props;
const showModal=()=>{
this.setState({
visible:true
});
};
const hideModal=()=>{
this.setState({
visible:false
});
};
const save=()=>{
this.props.form.validateFields((err,val)=>{
//val ==> record
// console.log(val);
ok(val);
hideModal();
});
};
return (
<div>
<span onClick={ showModal }>
{ children }
</span>
<Modal
title="Create User"
visible={ this.state.visible }
onCancel={ hideModal }
onOk={ save }>
<Form>
<Form.Item label="Name">
{
getFieldDecorator('name', {
initialValue: record.name
})(<Input />)
}
</Form.Item>
<Form.Item>
{
getFieldDecorator('age',{
initialValue:record.age
})(<Input />)
}
</Form.Item>
</Form>
</Modal>
</div>
);
};
}
export default Form.create()(UserModal);複製程式碼
usersPage.js
import { connect } from 'dva';
import Main from '../components/layout/main';
import UserTable from '../components/user/user';
const UserPage=()=>{
return (
<Main>
<h1>UserPage</h1>
<UserTable />
</Main>
);
};
export default connect()(UserPage);複製程式碼
10.效果演示
11.原始碼下載
或者 https://pan.baidu.com/s/1bo1R7o7