antd pro的底层基础框架使用的是dva,dva采用effect的方式来管理同步化异步
在dva中主要分为3层 services models components
models层用于存放数据以及对数据进行操作,services层调用请求后台接口的方法,components层用于书写页面逻辑代码
services层
import request from '@/utils/request';
export async function doit(payload) {
const {id} = payload;
let url = `/api/v2/.../${id}`;
return request(url,{
mode: 'cors',
method: 'GET',
})
.then(res => {
return res;
})
.catch(err => console.log(err));
}
models层中的effects是与后台交互、处理数据逻辑的地方
import {doit} from '../../'
export default {
namespace: 'test',
effects: {
*fetchNum ({payload,callback},{call,put}) {
const res = yield call (doit,payload)
//doit是引入services层那个js文件的doit方法,payload是后台要求传递的参数,res就是后台返过来的数据
yield put ({
type: 'addNum', //这就是reducer的addNum方法,put用来出发reducer中的方法,payload是传过去的参数。同时也能触发同等级effects中的方法
payload: {
num: res.data //把后台返回的数据赋值给num,假如哪个reducer中的方法是由这里effects去触发的,哪个num名必须是这里的名字num,如果reducer中的方法不是这触发,那名字可以随意取
}
})
}
}
reducers: {
addNum (state,{payload:{num}}) {
return {...state,num}
}
}
}
components层
页面如果需要使用models层的数据,要用connect进行连接,即在页面在引入import {connect} from 'dva';@connect(state => ({test:state.test})) 通过this.props获取数据
this.props.dispatch({
type: 'test/fetchNum', test对应models层的命名空间namespace
payload: {
numCount: ++1
}
})
使用mock数据主要包括以下几步:
1、添加mock接口
2、添加service文件
3、添加model(需引入service函数)
4、页面链接model
5、页面调用model中的effect函数
6、model中的effects通过reducer中的函数将数据返回到页面
7、页面通过this.props获取数据
具体操作就是在项目根目录下,mock文件夹中新建record.js文件,用于存放mock数据
export default { 'GET /love/record':{ message: 'Succeed', code:0, data: [ { key: '1', Name: '违规操作', age: '口腔科', address: '人民医院', tags: '2019-03-21 12:56:12', questions: '温度' }, { key: '2', Name: '违规操作', age: '皮肤科', address: '人民医院', tags: '2019-03-21 12:56:12', questions: '压力' }, ] } }
然后在src目录下的services文件夹中新建一个record.js文件,用来创建请求数据的函数,框架已经为我们封装好了request函数(可能需要我们对request.js文件进行补充),我们可以直接进行使用
import request from '../utils/request' ; export async function getRecord (payload) { return request('/love/record',{ //如果路径中有参数,需要用字符串模板进行拼接``
method: 'GET' }) .then(res => { return res; } .catch(err => console.log(err)) }
src目录下的models文件夹是store文件夹,用来定义state
新建record.js文件
引入我们在services文件夹中创建的请求数据的函数
import { getRecord } from '../services/record' ; export default { namespace: 'demo', state:{ record: [], }, effects: { *getRecord(payload,{call,put}) { const res = yield call(getRecord,payload) yield put({ type: 'updateToView', payload:{record:res.data} }); } }, reducers: { updateToView(state, { payload }) { return { ...state, ...payload, } } } }
最后在page页面中,通过this.props就可以得到我们想要的数据
import { connect } from 'dva' ; @connect(state=> ({ demo:state.demo }) componentDidMount(){ const { dispatch } = this.props; dispatch({ //需要调用对于namespace下effects中的该函数
type: 'record/getRecord', }) } console.log(this.props)就可以得到结果 const { demo } = this.props
我的request.js文件
import fetch from 'dva/fetch'; import { message } from 'antd'; import { error } from '@/utils/error'; const checkStatus = response => { if (response.status >= 200 && response.status < 300) { return response; } const errortext = error[response.status] || response.statusText; let isLogin = response.url.search('/unsecure/login') != -1; if (response.status === 401) { if (isLogin) { message.error(`请求错误 ${response.status}: ${errortext}`); } else { console.log('gogogo') router.push('/user/login'); } } else { if (!isLogin) { message.error(`请求错误 ${response.status}: ${errortext}`); } } return response; }; export default function request(url, option) { //获取token
let token = localStorage.getItem('token'); const options = { ...option, headers: { 'X-Authorization': token, 'x-language': 'chinese', }, }; const newOptions = { ...options, credentials: 'include' }; if ( newOptions.method === 'POST' || newOptions.method === 'PUT' || newOptions.method === 'DELETE' ) { if (!(newOptions.body instanceof FormData)) { newOptions.headers = { Accept: 'application/json', 'Content-Type': 'application/json; charset=utf-8', ...newOptions.headers, }; if (newOptions.dataType != 'string') { newOptions.body = JSON.stringify(newOptions.body); } } else { newOptions.headers = { Accept: 'application/json', ...newOptions.headers, }; } } return ( fetch(url, newOptions) .then(checkStatus) .then(response => { if (newOptions.responseType === 'blob') { return response.blob(); } let type = typeof response; switch (type) { case 'object': return response.json(); case 'string': return response.text(); } return response.json(); }) .then(res => { return res; }) .catch(e => { }) ); } error.js文件 export default { 40101: '再输错两次将锁住', 40200: '用户不存在', 200: '服务器成功返回请求的数据。', 201: '新建或修改数据成功。', 202: '一个请求已经进入后台排队(异步任务)。', 204: '删除数据成功。', 400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。', 401: '用户权限错误。', 403: '权限信息错误。', 404: '发出的请求针对的是不存在的记录,服务器没有进行操作。', 406: '请求的格式不可得。', 410: '请求的资源被永久删除,且不会再得到的。', 422: '当创建一个对象时,发生一个验证错误。', 500: '服务器发生错误,请检查服务器。', 502: '网关错误。', 503: '服务不可用,服务器暂时过载或维保。', 504: '网关超时。', }