dva
的幾個關鍵詞的做用model
中定義state
,用於分模塊管理全局狀態redux-sagas
作異步流程控制,因爲採用了generator
的相關概念,因此將異步轉成同步寫法vuex
中的Action
,包含異步操做,在vuex
中用於提交mutation
,從而變動state
,在dva
中用於提交reducer
,用於修改state
state
的地方,經過effect
經過actions
傳入的值修改state
vuex
中mutation
。dispatch
一個payload
參數在model
文件中使用yield
call
發起ajax請求//getDetailDiscount 接口名 //payload 參數 yield call(getDetailDiscount, payload)
put
關鍵詞提交Reducer
//doDiscounts 一個名字爲doDiscounts的同步方法 修改state yield put({type: 'doDiscounts', payload: response.data});
effect
中能夠經過select
獲取model
中state
state
state:{ num:1 }
effect
effect:{ *getNum({payload},{select}){ //獲取state中的num const num = yield select(state => state.num) } }
跨model
獲取state
javascript
other字段爲model
的namespace
effect:{ *getOtherNum({payload},{select}){ //獲取state中的num const num = yield select(state => state.other.num) } }
dva裏的model主要是用來開始處理數據和邏輯的。
dva 經過 model 的概念把一個領域的模型管理起來,包含同步更新 state 的 reducers,處理異步邏輯的 effects,訂閱數據源的 subscriptions 。html
新建一個一個model/users.js
vue
export default { namespace: 'users', state: [], reducers: { doSearch (state, { payload}){ return { ...state, searchRsp: payload.data, } }, }, effects:{ * handleGetSearch({payload, searchRspCallBack}, {call, put}) { LogTag('****************************handleGetSearch req*************', payload); const response = yield call(getSearch, payload); LogTag('****************************handleGetSearch rsp*************', response); if (response.status === 200 && response.data.status === 0) { searchRspCallBack(response.data.result) } else if (response.status === 200 && response.data.status === 1) { message.error(response.data.msg) yield put({ type: 'doSearch', payload: response.data, }); } }, subscriptions :{ } };
新建ApiService.js文件java
import request from '../utils/request'; import {stringify} from 'qs'; /* * 搜索 * */ export async function getSearch(params) { return request(`/search?${stringify(params)}`); }
這裏我主要在effects 定義了一個handleGetSearch
方法,
這個方法簡單理解:react
一、paload是接口的參數,這裏打印一下 二、searchRspCallBack是一個回調方法, 主要是在接口正常調用以後將響應內容在頁面層使用 三、yield call(getSearch, payload);是一個異步調用接口參數的方法 四、上述中的if判斷主要是說在接口響應到的數據爲我與後臺正肯定義的返回碼才進行相應的操做, 好比這裏我跟後臺約定的是status === 0正常 status === 1 打印後臺返回的錯誤信息 五、searchRspCallBack(response.data.result) 調用傳過來的回調將接口返回數據做爲參數傳進去
reducers
方法:用於執行同步操做,改變state等git
return { ...state, searchRsp: payload.data, } 改變model中state的searchRsp值爲接口返回的響應內容
model中異步獲取數據的方法定義好以後如何使用呢?github
this.props.dispatch({ type: 'users/handleGetSearch', payload: { keywords: this.state.searchText, limit: this.state.limit }, searchRspCallBack: this.handleSearchRspCallBack }) handleSearchRspCallBack = (rsp)=>{ LogTag(rsp) }
這是dva中使用dispatch調用model中方法的寫法,注意在使用此方法以前要先使用 connect
將model與component鏈接起來,若是你熟悉 redux,這個 connect 就是 react-redux 的 connect 。web
這裏使用註解的方法使用connectajax
@connect(({users, loading}) => ({ users, }))
上述dispatch的簡單解釋:vuex
一、type爲要調用的哪一個model中的哪一個方法, 二、payload爲傳的參數,這裏傳了一個keyword與limit數量過去 三、searchRspCallBack: this.handleSearchRspCallBack的意思是將本地的一個方法做爲參數傳遞到model中, 若是model中正確響應以後將響應的內容做爲參數傳遞到這個方法中, 而後我本地寫一個handleSearchRspCallBack方法用來接收響應 這樣我在component層就能夠拿到接口響應的內容了
這是我用來獲取接口異步數據的方法第一種,還有一種就是以前在model中執行了reducer
同步方法將接口返回的數據保存在了model中的state裏面,在componentWillReceiveProps鉤子函數也能夠拿到咱們須要的響應
componentWillReceiveProps(nextProps){ if(nextProps){ LogTag(nextProps.users.searchRsp) } }
上述中nextProps.users.searchRsp
就是接口返回的值了
一、先在model中定義一個方法用來執行異步調用接口的方法,能夠直接使用回調方法的方法將響應做爲參數回調,也可使用同步reducer的方法將數據保存在state中,後面component層去取model中state的值
二、兩種方法均可以獲取到異步調用接口返回的響應,第一種好須要定義一個回調方法,第二種獲取model中state值須要定義state,在不一樣的場景使用不一樣的方法
callback
很是的不優美,這裏官方其實早已提供promise
的寫法*handleUpdateBasicInfo({ payload, user }, { call, put, select }){ const response = yield call(postUpdateBasicInfo, payload); if (response && response.status === 0) { return response.data } }, //這裏在effect中直接return 咱們想知道的結果 handleUpdateBasicInfo = (params) => { const { dispatch } = this.props; dispatch({ type: 'user/handleUpdateBasicInfo', payload: { ...params, }, }).then(res=>{ console.log('res',res) }) }; //這裏then中能夠獲取到數據