关于dva实际应用的一些经验以及疑惑

从开始学习dva到引入到实际项目中也有几个月的时间,下面分享一下实际的经验,另外也有一些比较含糊或者疑惑的地方,看看大家有没有有些好的思路。
dva整体构架比较清晰,但是实际使用的时候,还是需要做很多处理。

dva model扩展

在我们的基础库中,实现了Model.extend方法,所有的model都通过这个方法来创建, extend具体对以下几个方面进行了扩展.

state

根据我们的业务特点(主要为管理系统),每个model我们都默认添加了loading, confirmLoading, spinner属性

subscriptions

subscriptions中对路由的监听 写法太过繁琐,特别是在包含参数的情况下。我们扩展了实现了listen方法

subscriptions: {
    setup({ dispatch, listen }) {
      
      //action为 redux action
      listen('/user/list', { type: 'fetchUsers'});

      //action为 回调函数
      listen('/user/:id/detail', ({ query, params }) => {
        const id = params[0];
        dispatch({
          type: 'fetchDetail',
          payload: { id }
        })
      });

      //支持对多个path的监听
      listen({
        '/user/list': ({ query, params }) => {},
        '/user/query': ({ query, params }) => {},
      });
  }

effects扩展

dva中处理loading状态非常繁琐,而dva提供的全局loading对我们业务并不适用,因为往往一个model中,有些call请求需要loading,有些call请求又不需要loading,所以我们对effects中的saga函数进行了扩展

  • callWithLoading 调用请求时,自动处理loading状态
  • callWithConfirmLoading 调用请求时,自动处理confirmLoading状态
  • callWithSpinning 调用请求时,自动处理spinning状态

如果发送ajax请求,需要处理相关的状态,就可以使用上面的方法,如果不需要就使用原始的call方法, 使用开发中可以灵活选择.
另外,在我们的业务中,call请求成功或者失败后,往往需要弹出对应的业务提示框(消息内容有时候不是由后端提供),故我们在上面的函数中,都提供额外的参数,支持请求结果的消息框处理。

//请求开始前会将loading = true,  请求结束后,将loading=false
const users = yeild callWithLoading(service.user.getList,user);
const users = yeild callWithLoading(service.user.getList,user,{successMsg:'加载用户成功',errorMsg:'加载用户失败'});

effects中经常需要需要更新state,但是往往又不想为每次修改都命名一个reducer函数,所以扩展了update方法,调用updateState reducer来更新state

//更新当前model的state
yield update({ users })

reducers扩展

为了配合effects中的扩展,我们默认实现了如下方法
showLoading,hideLoading... 等加载状态控制方法
updateState 直接更新state数据
resetState 重置state数据

request 扩展

fetch在实际项目中用使用,实在太过鸡肋,我们在fetch的基础上封装了Http类,实现了简单的中间件机制,方便各个项目使用,并且实现了一些常见的中间件(token中间件,统一错误弹框中间件等)

export default Http.create([dataTransformMiddleware, domainMiddleware, contentMiddleware, headerMiddleware]);

antd form扩展

antd form写法 个人觉得实在太过繁琐,一个带表单验证的输入框,往往需要FormItem & getFieldDecortor & Input 三层结构,而且混合着jsx以及js的语法.
为了简化form相关的代码,我们重新定义了field属性结构,并且提供了HForm 以及HFormItem组件。

HForm 主要应用与一些简单的form表单,不需要太多的交互
HFormItem 则是form中每一项输入框,用于复杂布局/交互的form中

const fields = [
  {
    key: 'name',
    name: '名称',
    required: true,
  }, {
    key: 'gender',
    name: '性别',
    enums: {
      MALE: '男',
      FAMALE: '女'
    }
  }, {
    key: 'birthday',
    name: '生日',
    type: 'date'
  }
];

function HFormBase({ form }) {
  const formProps = {
    fields
    item: {},
    form
  };
  const onSubmit = () => {
    validate(form, fields)((values) => {
      results = values;
    });
  };

  return (
    <div>
      <HForm {...formProps} />
      <Button onClick={onSubmit} type="primary" >提交</Button>
    </div>
  );
}
const fields = [
  {
    key: 'name',
    name: '名称',
    required: true
  }, {
    key: 'age',
    name: '年龄'
  }, {
    key: 'birthday',
    name: '生日',
    type: 'date'
  }, {
    key: 'desc',
    name: '自我介绍',
    type: 'textarea'
  }
];


function HFormItemBase({ form }) {
  const layout = {
    labelCol: { span: 6 },
    wrapperCol: { span: 18 }
  };
  const itemProps = { form, item: {}, ...layout };
  const rules = {
    number: [{ pattern: /^\d+$/, message: '请输入数字' }]
  };
  const submit = () => {
    validate(form, fields)((values) => {
      console.log(values);
    });
  };
  const fieldMap = getFields(fields).toMapValues();

  return (
    <Form >
      <Row>
        <Col span="12" ><HFormItem {...itemProps} field={fieldMap.name} inputProps={{ disabled: true }} placeholder="指定placeholder" /></Col>
      </Row>
      <Row>
        <Col span="12" ><HFormItem {...itemProps} field={fieldMap.age} rules={rules.number} onChange={onChange} /></Col>
        <Col span="12" ><HFormItem {...itemProps} field={fieldMap.birthday} /></Col>
      </Row>
      <Row>
        <Col span="12" ><HFormItem {...itemProps} field={fieldMap.desc} /></Col>
      </Row>
      <Row>
        <Col span="12"><Button type="primary" onClick={submit} >提交</Button></Col>
      </Row>
    </Form>
  );
}

原文:https://github.com/dvajs/dva/issues/886

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值