官網上介紹:dva 是基於redux,redux-saga和react-router的輕量級前端框架。也就是 dva 主要是基於 redux 和 redux-saga 的數據流解決方案,內置了 react-router 和 fetch。javascript
dva 是 antd design pro 基於 React 的中後臺管理控制檯的腳手架選擇的數據流管理框架,作 antd-pro 搭建的項目的時候開始接觸到這個框架,在腳手架造成的目錄中:dva 分別在 '/src/models' 中管理全局數據,在 '/pages/肯定的某一頁面/models' 中管理某一頁面的數據。html
下面代碼是在 antd-pro 腳手架搭建起來的項目中的實踐,原理部分的掌握還欠缺,先記下來經常使用的用法,和基礎知識。前端
// connect 也是鏈接的數據是對 store 中的數據的淺複製,當是引用類型的數據的時候,若是直接修改 props 中映射數據, store 裏面的數據也會被修改
@connect(state => ({
detailsTable: state['event/addNewCard'],// 這裏傳入的 state 參數是一個「徹底體」,包含了全部 namespace 下的 state,以 namespace 爲 key 值進行區分
loading: state.loading,
layout: state.layout,
}))
export default class PuzzleCardsPage extends Component {
addNewCard(){
dispatch({
type:'event/addNewCard',
payload:{},//傳遞數據的載體
//還能夠傳進去一個回調函數,處理當數據沒有正確請求的時候的處理邏輯
callback: res => {
message.error(res)
}
})
}
render() {
return (
<div> <Button onClick={this.addNewCard}> 添加卡片 </Button> </div>
);
}
}
複製代碼
export default {
namespace: '',//不一樣的頁面或操做對應不一樣的命名空間
state:{},
effects:{//至關於 redux 的 middleware,爲了保證 reducer 的純粹性,有一些須要對數據在進行處理的操做放在 effects 裏面,好比在 effects 裏面能夠調用 services 方法進行異步請求。
*addByONe({payload, error}, { call, put, select }) { // 傳入這個 Generator 函數的有兩個參數,一個是匹配這個 effects 的 action 對象,所以能夠取到 payload 和 error 字段。 另外一個是 effect 原語集,call 主要處理異步邏輯(好比發起請求)它第一個參數是一個函數,要求函數返回 Promise,以後的參數是該函數調用時的入參。
const num = yield select(state => state.num) // effects 裏面主要經過yield select 獲取 state
let param1;
param1 = num + param;
yield put({//effects 裏面經過 put 方法觸發 action,和 pages 中的dispatch 方法如出一轍,能夠繼續請求其餘 namespace 中的 effects 或者 reducer ,不一樣的是,請求自身的 effects 或者 reducer 時不須要指定 namespace 名稱
type: 'save',
num:param1
});
}
},
//用來保存更新 state 值 上面的 put 方法調用這裏的方法,當不須要發起請求,只修改state中數據的方法放在這裏,且這裏的方法也可以被外部調用
reducers: {
save(state, action) { //state 是當前命名空間的 state,這裏的 action 包含了上面傳遞的參數和 type
return { ...state, ...action.num };
},
},
}
複製代碼
model 中幾個基本屬性,其中 namespace 和 state 是一個 model 中最基本的兩個成員。java
namespace
:model 的命名空間,只能用字符串,是一個 model 的惟一標識。一個大型應用可能包含多個 model,經過 namespace 區分。state
:當前 model 狀態的初始值,表示當前狀態。是該 model 管理的數據reducers
:用於處理同步操做,更新修改 state,由 action 觸發。reducer 是一個純函數,它接受當前的 state 及一個 action 對象。action 對象裏面能夠包含數據體(payload)做爲入參,須要返回一個新的 state。effects
:用於處理異步操做(例如:與服務端交互)和複雜的數據處理邏輯,也是由 action 觸發。可是,它不能夠修改 state,要經過觸發 action 調用 reducer 實現對 state 的間接操做。action
:是 reducers 及 effects 的觸發器,通常是一個對象,形如{ type: 'add', payload: todo },經過 type 屬性能夠匹配到具體某個 reducer 或者 effect,payload 屬性則是數據體,用於傳送給 reducer 或 effect。dva-loading
插件,可是使用腳手架搭建項目,直接在頁面中使用就能夠了,經過 connect 方法將加載的狀態傳遞到組件中,下面是幾種具體的方法:(1)loading.effects['chart/fetch']
監聽這個方法是否執行完畢,若執行完畢。loading 的值就變爲 false。react
@connect(({ chart, loading }) => ({
chart,
loading: loading.effects['chart/fetch'],
}))
複製代碼
(2)loading.models.monitor
監聽這個模塊是否執行完畢,注意這裏的 [monitor] 是命名空間。監聽的是當前頁面用到的命名空間裏面的方法。若執行完畢,loading 的狀態變爲 false。git
@connect(({ monitor, loading }) => ({
monitor,
loading: loading.models.monitor,
}))
複製代碼
(3)還有一種用法是 loading.global,經過全局的狀態控制 loading 的狀態。loading.global
監聽這個頁面的加載狀態。當頁面處於異步加載狀態時該值爲 true,當頁面加載完成時,自動監聽該值爲 false。github
這裏是綁定到 dva 的自動控制 loading 數據的插件。再也不須要重複寫 showLoading 和 hideLoading。redux
文檔中講的很清楚,並且在掌握上面的基礎知識後,也不難上手使用這個框架。前端框架
// 建立應用
const app = dva();
// 註冊 Model
app.model({
namespace: 'count',
state: 0,
reducers: {
add(state) { return state + 1 },
},
effects: {
*addAfter1Second(action, { call, put }) {
yield call(delay, 1000);
yield put({ type: 'add' });
},
},
});
// 註冊視圖
app.router(() => <ConnectedApp />);
// 啓動應用,將組件掛載到 id 爲 root 的元素上
app.start('#root');
複製代碼