Ant Design Pro是一款搭建中後臺管理控制檯的腳手架 ,基於React,dva.js,Ant Designjavascript
(1)其中dva主要是控制數據流向,是純粹的數據流,用做狀態管理html
使用React技術棧管理大型複雜的應用每每要使用Redux來管理應用的狀態,然而隨着深度使用,Redux也暴露出了一些問題。dva 是一種改良Redux的架構方案,是基於現有應用架構 (redux + react-router + redux-saga 等)的一層輕量封裝,簡化了redux和redux-saga使用上的諸多繁瑣操做。java
(2)ant design是一個基於react打造的一個服務於企業級產品的UI框架。react
以路由爲基礎,用來控制路由redux
一、使用Ant Design pro腳手架官網來搭建項目,根據官網教程比較容易,api
根據官網可知,使用ant design pro生成的項目目錄爲:瀏覽器
其中最重要的四個文件夾,services、models、mock、pages服務器
pages觸發models中的方法來處理數據,若爲異步操做在models中須要調用services中的數據接口方法,在後臺未寫完時能夠經過mock中的模擬數據來調試antd
具體來講,也便是使用dva時,數據流向或者說觸發流程爲:在pages中的jsx文件中經過dispatch觸發models中的js文件中的effects或者reducers中的方法,其中effects中的方法是異步操做,經過yield call(調用接口函數方法名)調用從services中js文件引入的定義好的調用接口方法,而後經過yield put({type: 'reduceres中的方法'});來觸發 reducers中的方法來修改state。react-router
數據流向圖以下:
數據的改變發生一般是經過:
當此類行爲會改變數據的時候能夠經過 dispatch 發起一個 action,若是是同步行爲會直接經過 Reducers 改變 State ,若是是異步行爲(反作用)會先觸發 Effects 而後流向 Reducers 最終改變 State 。
簡單的實例以下:
一、welcome.jsx文件
import React from 'react';
import { Form, Input, Button, InputNumber } from 'antd';
import { connect } from 'dva';
//將form注入到props中 @Form.create() //將models中的狀態state綁定到props中,解構出myInfo,以myInfo命名綁定到props上 @connect(({lhj:{myInfo}})=>({ //箭頭函數返回一個對象,必須在對象外面加上一個括號 myInfo }))
class Welcome extends React.Component{
handleSubmit = e=>{
const { form, dispatch } = this.props;
e.preventDefault();
//校驗輸入域的值
form.validateFields((err,values) =>{
if(!err){
console.log(values);
//驗證成功 傳入對象{type: 'lhj/check',payload: {...values,}},調用lhj中的check函數,
dispatch({ type: 'lhj/check', payload: { ...values, } });
}
})
//console.log('submit',form.getFieldValue('username'));
}
handleReset = ()=>{
this.props.form.resetFields();
}
render(){
const { getFieldDecorator } = this.props.form;
return (
<div>
<Form onSubmit={this.handleSubmit} layout="inline">
<Form.Item label="姓名">
{getFieldDecorator('username', {
rules: [{required: true, message: 'please input your username'}]
})(<Input placeholder="username"/>)}
</Form.Item>
<Form.Item label="年齡">
{getFieldDecorator('age',{
rules: [
// {type: 'number', message: 'this must be a number'},
{required: true, message: 'please input your age'}
]
})(<InputNumber placeholder="age"/>)}
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">查詢</Button>
</Form.Item>
<Form.Item>
<Button onClick={this.handleReset}>取消</Button>
</Form.Item>
</Form>
{this.props.myInfo.username}-{this.props.myInfo.age}
</div>
);
}
}
export default Welcome;
二、services/lhj.js文件
import request from '@/utils/request';
export async function lhjCheck(params){
console.log(params,'services')
return request('/api/lhj', { params });
}
三、models/lhj文件
import {lhjCheck} from '@/services/lhj';
const lhjModel = {
namespace: 'lhj',
state: {
myInfo: {
username: '',
age: 0,
}
},
effects: {
*check({ payload },{ call, put }){
// console.log(payload,'lhj/check');
const res = yield call(lhjCheck, payload);
// console.log(res,'res');//res爲從mock中返回的虛擬數據
yield put({ type: 'checkInfo', payload: { myInfo: res }, })
},
},
reducers: {
checkInfo(state, { payload }){ console.log(state,payload,'checkInfo'); return { ...state, ...payload,//同名的會覆蓋掉 } },
saveInfo(state){
return {
}
},
}
}
export default lhjModel;
四、mock/lhj.js文件
export default {
'Get /api/lhj': {
username: 'lhj',
age: 24
},
}
3、幾個知識點總結:
一、connect的做用是將組件和models結合在一塊兒。將models中的state綁定到組件的props中。並提供一些額外的功能,譬如dispatch。經過connect
來綁定model state。意味着Component裏能夠拿到Model中定義的數據,Model中也能接收到Component裏dispatch的action。實現了Model和Component的鏈接。注意@connect必須放在export default class前面
當在組件裏發起action時,直接dispatch就好了(
dispatch({ type: `monthCard/query`, payload: {}//須要傳遞的數據 })
),dva會幫你自動調用effects/reducers。當發起同步action時,type寫成'(namespace)/(reducer)'
dva就幫你調用對應名字的reducer直接更新state,當發起異步action,type就寫成'(namespace)/(effect)'
,dva就幫你調用對應名字的effect,而後經過yield put調用reducer來實現異步更新state
三、項目的開發流程通常是從設計model state開始進行抽象數據,完成component後,將組件和model創建關聯,經過dispatch一個action,在reducer中更新數據完成數據同步處理;當須要從服務器獲取數據時,經過Effects數據異步處理,而後調用Reducer更新全局state。是一個單向的數據流動過程。