1.0.3 • Published 3 years ago

@ctsj/dvagenerator v1.0.3

Weekly downloads
4
License
MIT
Repository
github
Last release
3 years ago

CTSJ-DvaGenerator

dva数据流的一个生成器,能通过Service自动生成组件的mapStateToProps、mapDispatchToProps和Model

简介

一个简单的例子,用dva编写一个标椎的用户模块,用户模块中是标准的CRUD操作,我们大致会这样去写

  1. 定义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');
}
  1. 定义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,
        };
      },
    },
  };
  1. 定义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,我们只处理标椎模块,如果自动生成的这三部分不能满足需求,可以进行重写覆盖

处理

  1. mapStateToProps
  return {
    [namespace]: state[namespace],
    loading: state.loading.global
  };
  1. mapDispatchToProps 和Service方法一一对应,例如 `
  mapDispatchToProps[methodName] = params => dispatch(Object.assign({ type }, params));
  1. Model
  namespace,
  effects: {},
  reducers: {
    receive(state, { payload }) {
      return {
        ...state,
        ...payload
      };
    }
  }
  1. effects中的方法和Service的方法一一对用,effects中的方法只做三件事
  2. 调用Service中相应接口
  const response = yield call(Service[key], other);
  1. 调用success回调函数
  const { codeKey, codeSuccessKey, dataKey, messageKey } = Service.default;
  if (response[codeKey] === codeSuccessKey) {
    if (success) {
      success(response[dataKey],response[messageKey]);
    }
    ...
  }
  1. 调用receice的reduce
  yield put({
    type: "receive",
    payload: { [service对应的方法名]: 接口返回数据 }
  });
  1. 完整的操作
  // 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] }
    });
  }
  1. 处理完成之后我们的UserPage的props中会有如下数据
  {
    user: {
      fetchList:[],
      fetchInfo:{},
      fetchSave:{},
      fetchDelete:{},
      fetchUpdate:{},
    }
  }

安装

  npm install @ctsj/dvagenerator

例子

  1. 定义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',
  };
  1. 定义UserModel
  import ServiceRegister from '@ctsj/dvagenerator';

  export default Object.assign(ServiceRegister.model('user'), {
    state: {
      fetchList: [],
    },
    subscriptions: {
      setup({ history, dispatch }) {
        console.log('user', 'setup');
      },
    },
  });
  1. 定义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);
  1. 注册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工程

1.0.3

3 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago