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中能够获取到数据