一、簡介
1、Ant Design Pro
Ant Design Pro是一款搭建中後臺管理控制檯的腳手架 ,基於React,dva.js,Ant Design
(1)其中dva主要是控制資料流向,是純粹的資料流,用作狀態管理
使用React技術棧管理大型複雜的應用往往要使用Redux來管理應用的狀態,然而隨著深度使用,Redux也暴露出了一些問題。dva 是一種改良Redux的架構方案,是基於現有應用架構 (redux + react-router + redux-saga 等)的一層輕量封裝,簡化了redux和redux-saga使用上的諸多繁瑣操作。
(2)ant design是一個基於react打造的一個服務於企業級產品的UI框架。
2、umiJS是一個控制路由
以路由為基礎,用來控制路由
二、實踐分析
1、使用Ant Design pro腳手架官網來搭建專案,根據官網教程比較容易,
根據官網可知,使用ant design pro生成的專案目錄為:
其中最重要的四個資料夾,services、modles、mock、pages
- sevices:資料介面
- modles:資料處理
- mock:模擬資料
- pages:頁面
pages觸發modles中的方法來處理資料,若為非同步操作在modles中需要呼叫services中的資料介面方法,在後臺未寫完時可以通過mock中的模擬資料來除錯
具體來說,也即是使用dva時,資料流向或者說觸發流程為:在pages中的jsx檔案中通過dispatch觸發models中的js檔案中的effects或者reducers中的方法,其中effects中的方法是非同步操作,通過yield call(呼叫介面函式方法名)呼叫從services中js檔案引入的定義好的呼叫介面方法,然後通過yield put({type: 'reduceres中的方法'});來觸發 reducers中的方法來修改state。
資料流向圖如下:
資料的改變發生通常是通過:
- 使用者互動行為(使用者點選按鈕等)
- 瀏覽器行為(如路由跳轉等)觸發的
當此類行為會改變資料的時候可以通過 dispatch 發起一個 action,如果是同步行為會直接通過 Reducers 改變 State ,如果是非同步行為(副作用)會先觸發 Effects 然後流向 Reducers 最終改變 State 。
簡單的例項如下:
1、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,以data命名繫結到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;
2、services/lhj.js檔案
import request from '@/utils/request';
export async function lhjCheck(params){
console.log(params,'services')
return request('/api/lhj', { params });
}
3、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;
4、mock/lhj.js檔案
export default {
'Get /api/lhj': {
username: 'lhj',
age: 24
},
}
三、幾個知識點總結:
1、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
3、專案的開發流程一般是從設計model state開始進行抽象資料,完成component後,將元件和model建立關聯,通過dispatch一個action,在reducer中更新資料完成資料同步處理;當需要從伺服器獲取資料時,通過Effects資料非同步處理,然後呼叫Reducer更新全域性state。是一個單向的資料流動過程。