1.0.3 • Published 3 years ago
@ctsj/dvagenerator v1.0.3
CTSJ-DvaGenerator
dva数据流的一个生成器,能通过Service自动生成组件的mapStateToProps、mapDispatchToProps和Model
简介
一个简单的例子,用dva编写一个标椎的用户模块,用户模块中是标准的CRUD操作,我们大致会这样去写
- 定义UserService,UserService大致会是这样
import { stringify } from 'qs';
import request from '@/utils/request';
// 列表
export async function fetchtList(params) {
return request.get('fetchList');
}
// 详情
export async function fetchtInfo(id) {
return request.get('fetchtInfo');
}
// 添加
export async function fetchtSave(payload) {
return request.post('fetchSave');
}
// 删除
export async function fetchtDelete(id) {
return request.delete('fetchtDelete');
}
// 修改
export async function fetchtUpdate(payload) {
return request.put('fetchtUpdate');
}
- 定义UserModel,UserModel大致会是这样
import {
fetchtList,
fetchtInfo,
fetchtSave,
fetchtDelete,
fetchtUpdate,
} from '@/services/UserService';
export default {
namespace: 'user',
state: {
data: {
list: [],
total: 0,
},
},
effects: {
// 列表
*fetchList({ payload }, { call, put, select }) {
const response = yield call(fetchtList, payload);
if (response.code === 0) {
yield put({
type: 'receive',
payload: response.data,
});
}
},
// 详情
*fetchInfo({ payload:{id} }, { call, put, select }) {
const response = yield call(fetchInfo, id);
if (response.code === 0) {
yield put({
type: 'receive',
payload: response.data,
});
}
},
// 添加
*feachSave({ payload: { success, ...other } }, { call, put }) {
const response = yield call(fetchtSave, other);
if (response.code === 0) {
if (success) {
success();
}
yield put({ type: 'fetchList', payload: {page:0,limit:10} });
}
},
// 修改
*feachUpdate({ payload: { success, ...other } }, { call, put }) {
const response = yield call(feachUpdate, other);
if (response.code === 0) {
if (success) {
success();
}
yield put({ type: 'fetchList', payload: {page:0,limit:10} });
}
},
// 删除
*feachDelete({ payload: { success, id } }, { call, put }) {
const response = yield call(feachDelete, id);
if (response.code === 0) {
if (success) {
success();
}
yield put({ type: 'fetchList', payload: {page:0,limit:10} });
}
},
},
reducers: {
receive(state, { payload }) {
return {
...state,
...payload,
};
},
},
};
- 定义UserPage, UserPage大致会是这样
import React from 'react';
import { connect } from 'dva';
class User extends React.Component {
...
}
const mapStateToProps = ({ user, loading }) => ({
user,
loading: loading.global,
});
const mapDispatchToProps = dispatch => ({
fetchList: payload => dispatch({ type: 'user/fetchList', payload }),
fetchInfo: payload => dispatch({ type: 'user/fetchInfo', payload }),
fetchSave: payload => dispatch({ type: 'user/feachSave', payload }),
fetchDelete: payload => dispatch({ type: 'user/fetchDelete', payload }),
fetchUpdate: payload => dispatch({ type: 'user/fetchUpdate', payload }),
});
export default connect(mapStateToProps, mapDispatchToProps)(User);
我们会发现一个问题,像这样比较常规的CRUD操作,从Service -> Model -> Component的mapDispatchToProps方法的名字都是一一对应的, 而Model中的Effects操作基本都是调用Service中相应的接口,并且注入到数据流当中,而且Service也是按照相应模块编写的比如UserService就是处理User相关的操作, 这样就和Model中的namespace相对应,再则Model中的reducers里面应该只有一个receive的reducer,不应该有多个处理,effects中所有的put(reducer)都应该调用put({type:'receive'})来进行处理 所以我们就可以根据Service自动生成mapDispatchToProps和Model中的effects和reducers,我们只处理标椎模块,如果自动生成的这三部分不能满足需求,可以进行重写覆盖
处理
- mapStateToProps
return {
[namespace]: state[namespace],
loading: state.loading.global
};
- mapDispatchToProps 和Service方法一一对应,例如 `
mapDispatchToProps[methodName] = params => dispatch(Object.assign({ type }, params));
- Model
namespace,
effects: {},
reducers: {
receive(state, { payload }) {
return {
...state,
...payload
};
}
}
- effects中的方法和Service的方法一一对用,effects中的方法只做三件事
- 调用Service中相应接口
const response = yield call(Service[key], other);
- 调用success回调函数
const { codeKey, codeSuccessKey, dataKey, messageKey } = Service.default;
if (response[codeKey] === codeSuccessKey) {
if (success) {
success(response[dataKey],response[messageKey]);
}
...
}
- 调用receice的reduce
yield put({
type: "receive",
payload: { [service对应的方法名]: 接口返回数据 }
});
- 完整的操作
// 1.调用接口
const response = yield call(Service[key], other);
// Service中的默认导出必须有的键
// codeKey为状态域
// codeSuccessKey为状态域中成功标识
// dataKey为数据域
const { codeKey, codeSuccessKey, dataKey, messageKey } = Service.default;
if (response[codeKey] === codeSuccessKey) {
// 如果有success调用success传递data和message
// 2.调用回调函数
if (success) {
success(response[dataKey],response[messageKey]);
}
// 向数据流里放入Service的方法名为key,response[dataKey]为值的数据
// 3.调用数据流
yield put({
type: "receive",
payload: { [key]: response[dataKey] }
});
}
- 处理完成之后我们的UserPage的props中会有如下数据
{
user: {
fetchList:[],
fetchInfo:{},
fetchSave:{},
fetchDelete:{},
fetchUpdate:{},
}
}
安装
npm install @ctsj/dvagenerator
例子
- 定义UserService
import { stringify } from 'qs';
import request from '@/utils/request';
// 列表
export async function fetchtList(params) {
return request.get('fetchList');
}
// 详情
export async function fetchtInfo(id) {
return request.get('fetchtInfo');
}
// 添加
export async function fetchtSave(payload) {
return request.post('fetchSave');
}
// 删除
export async function fetchtDelete(id) {
return request.delete('fetchtDelete');
}
// 修改
export async function fetchtUpdate(payload) {
return request.put('fetchtUpdate');
}
// 默认导出与接口先关的参数
export default {
// 接口成功失败的状态键
codeKey: 'code',
// 接口成功的状态值
codeSuccessKey: 200,
// 接口数据的键
dataKey: 'data',
// 接口消息键
messageKey: 'message',
};
- 定义UserModel
import ServiceRegister from '@ctsj/dvagenerator';
export default Object.assign(ServiceRegister.model('user'), {
state: {
fetchList: [],
},
subscriptions: {
setup({ history, dispatch }) {
console.log('user', 'setup');
},
},
});
- 定义UserPage
import React from 'react';
import { connect } from 'dva';
import ServiceRegister from '@ctsj/dvagenerator';
class User extends React.Component {
...
}
const mapStateToProps = state =>
ServiceRegister.mapStateToProps({
namespace: 'user',
state,
});
const mapDispatchToProps = dispatch => ServiceRegister.mapDispatchToProps({
namespaces: ['user'],
dispatch,
});
export default connect(mapStateToProps, mapDispatchToProps)(User);
- 注册Service(在第一个执行文件执行的所有引用之后注册,umi是src/global.jsx)
import * as UserService from './service/UserService';
import ServiceRegister from '@ctsj/dvagenerator';
ServiceRegister.initConfig({
user: UserService,
});
API
initConfig - 服务注册初始化
mapStateToProps - 自动生成mapStateToProps
- mapDispatchToProps - 自动生成mapDispatchToProps
- model - 生成Service对应的Model
其他
demo目录下附带了一个todolist的demo,用的是umi的dva工程