dva-cli+ant-design的使用记录

这一套很多时候会拿来当做项目的后台管理系统,ant-design提供了丰富的组件,到目前为止使用的体感都很不错,在此记录一些搭建,以及使用时的历程,个人理解难免出现偏差,欢迎纠正。

0.初识DVA

dva 首先是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架 相比于create-react-app 构建的项目我认为dva更易于理解和学习。
那么dva里有什么呢?
过去曾写过react-native,理解过一些关于redux的东西,相较而言redux和dva概念很像,都是在View与数据之间增加了一层用于更新数据的Reducer。更新数据只能通过dispatch一个action,更新的数据也会直观的反应在View上。
dva应该是redux的超集,他提供了更方便的语法糖@connect,loading状态,提供了Effect来用于调用请求,发出action,此外还包含了react-router,fetch。可以说是一个完整的react数据流解决方案。
至于更深层次的理解,那就需要dva的源码解析

1.如何搭建?

搭建框架这东西还远为熟络,很多时候都是照着文档自己尝试的,很幸运的是ant-design的文档写的很好。
项目实战这里对如何搭dva的框架有了较为详细描述,可以酌情参考。

优化:
上述的简单配置还远未达到开发的要求,我们还需要:
1.动态加载models。
2.将HashRouter转化为BrowserRouter,去掉难看的‘#’。
3.线上配置router(使用数据库的数据)用于在应用中配置不同账号的权限。
4.封装请求,统一做错误判断。
5.配置代理,解决开发中的跨域问题,以及BrowserRouter带来的刷新问题。
6.其他......

2.各类组件使用心得

2.1 一切的开始:路由与Menu组件,路由是后台非常核心的一部分。

2.2 使用频率最高:Table组件
ant-design的表格自带有筛选,分页等功能,配合dva使用起来体感还不错。注意,table需要设置key,不然会报红,如果key相同则会出现难以预见的bug,具体可以尝试下就知道了。
此外和别的表格组件类似,他的显示控制可以在colums中做控制,render中同样可以做一些简单的三目判断。具体如下:

   const paginationProps = {
      showSizeChanger: true,
      showQuickJumper: true,
      ...ChannelDetail.managerLogs.pagination,
    };
      <Table
        loading={loading}
        dataSource={ChannelDetail.managerLogs.list}
        pagination={paginationProps}
        onChange={this.handleChange}
        columns={columns}
        // className="small-table"
      />
    const columns = [
      {
        title: '时间',
        dataIndex: 'createTime',
        key: 'createTime',
        render: text => {
          return moment(text).format('YYYY-MM-DD hh:mm:ss');
        },
      },
      //也可以简写为
      {
        title: '时间',
        dataIndex: 'createTime',
        key: 'createTime',
        render: text =>(moment(text).format('YYYY-MM-DD hh:mm:ss');) 
      },
    ];
复制代码

分页时,需要传入pagination,并再数据中有同名的分页字段,并再change方法中传入paginationProps中的分页字段名作为参数,loading用于loading状态的控制。
此外,antd自带的表格间距(padding)有些大,可以通过width来调整,而我则是写了个类名来统一缩小padding了。

2.3 非常强大的表单组件:Form
自带表单验证,数据提交等功能,虽然react的表单数据不能双向绑定,但有了他后数据就不需要走state了,他自带强大的set功能,并且自带表单验证,可以用正则,注意使用了FormItem后就不需要使用setState,以及value来做数据绑定了,this.props.form.setFieldsValue更适用,且不会报warning...,另外formItemLayout可以通过与antd的栅格插件来控制label与输入框的长度。示例:

    <FormItem label="分成比例" {...formItemLayout}>
      {this.props.form.getFieldDecorator('guanli', {
        rules: [
          { required: true, message: '管理员分成不能为空' },
          { pattern: /^100$|^(\d|[1-9]\d)(\.\d+)*$/, message: '分成比例应在0~100之间' },
        ],
        initialValue: 0,
      })(
        <Input
          placeholder="请输入管理员分成"
          onChange={e => {
            e.target.value != 0
              ? this.props.form.setFieldsValue({
                  guanli: e.target.value,
                  yuangong: 100 - e.target.value,
                })
              : this.props.form.setFieldsValue({ guanli: 0, yuangong: 0 });
          }}
          type="number"
        />
      )}
    </FormItem>
复制代码

FormItem的表单验证:

  subAdd = e => {
    const { dispatch } = this.props;
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        values.divideRatio = `${values.guanli}:${values.yuangong}`; //对参数格式做最后的控制
        dispatch({
          type: 'channel/addChannel',
          payload: {
            ...values,
          },
          callback: res => {
            if (res.code === 0) {
              message.success('添加成功!');
              this.props.form.resetFields();
              this.searchBtn();
              this.setState({ channelId: res.data, addModal: false, configModal: true });
            } else {
              message.error(res.msg);
            }
          },
        });
      }
    });
  };
复制代码

2.4 弹框Modal。antd的弹框自定义程度还是比较高的,其中包括了正常的弹框和确认框,不过弹框的位置应该不是按照居中来的,弹框较小的时候可能存在位置偏上的情况,如果设计要求较高,那就需要通过global来做矫正咯。
弹出框同样可以用来做成组件,配合上面的formItem使用也是可以的。如下,staffOk中两个参数分别为子组件传递的通过表单校验后的输入参数值,和一个重置表单的方法,这样就能在父组件中调用接口,并且重置表单。而addModal则用来控制子组件的显示与隐藏。

      <AddStaff
          handleOk={this.staffOk}
          ChannelList={dataall}
          handleCancel={this.staffCancel}
          addModal={this.state.staffModal}
          channelId={this.state.channelId}
          type={1}
        />
        
    staffOk = (e, func) => {
        this.setState({ addModal: false });
        const { dispatch } = this.props;
        dispatch({
          type: 'staff/addChannelStaff',
          payload: {
            ...e,
          },
          callback: res => {
            if (res.code === 0) {
              message.success('添加成功!');
              this.searchBtn();
              func(); // 子组件传递的重置表单方法
              this.setState({ staffModal: false });
            } else {
              message.error(res.msg);
            }
          },
        });
  };
复制代码

2.5 栅格组件,antd的栅格组件与bootstrap的类似,分为了24分,支持offset,push之类的位置调控,gutter来控制间距,提供响应式布局,此外还包含了flex的布局控制。

2.6 其他...

3.dva带来的方便与繁杂

3.1 dva-loading dva很强大一个功能来自于他的loding是自带的,能通过监听请求来设置loading的状态,而antd的loading组件很齐全,无论是表格的loading还是Spin组件都能很好的适配。但是dva的loading存在一个问题,当ajax请求出现服务器错误时,他是不会将loading状态取消的,而antd自带的处理是当接口报错时会自动跳转去相应的报错页面,而当你返回时,这个loading状态依然还在,并且只能通过重新加载浏览器才能取消,倘若后台接口处理不周,那尽量还是自己写loading的为好,此外,可能存在一些配置修改dva的loading来对接口报错做出反应,但是暂时不知如何处理......

3.2 redux的vm层中往往会在state中定义初始值,在定义的过程中尽量还是讲数据结构中会出现的层级都写进去,这样在首屏加载时就不会报一些空值的错误,也在后续的处理中方便很多。

3.3 异步请求。很多时候首屏的数据往往只需要一张表格,而后续的一些筛选条件,地区,以及选择列表可以后续加载,这时用异步请求就会大大提升用户体验。

4.eslint的爱与恨

4.1 为了代码规范化,项目中引入了eslint,为了适应其规范,同时引入了prettier来格式化代码,用的是windows的系统,可能会出现crlf 和lf 的报错,于是在.eslintrc文件 rules 里面 配置 "linebreak-style": [0 ,"error", "windows"]。

5.那些年我们踩过的坑

5.1 BrowserRouter带来的刷新浏览器报404的问题。单页应用在不做处理时刷新页面会去寻找路径下的资源而不是从index.js的入口进入,就会导致上述的问题。在开发过程中往往通过proxy做代理来解决这个问题。而在服务器上则需要对服务器做一些相应的配置。这里找到一个比较齐全的解决方案:解决方案

5.2 使用cnpm安装依赖会导致build无法使用的问题。

6.一些记录

6.1 为何对组件的样式修改中必须用:global()才能生效?
react引入了CSS Modules它自动为每一个类生成一个哈希值,可以惟一标志这个类,它让我们可以像使用js模块那样,想用哪部分样式,就引入哪部分样式。但是对组件赋予className时这是通过组件封装将传入值赋予这个组件的class,不会有哈希值,所以这时候就需要:global(),:global()代表的全局变量是不会附加哈希值的,这时样式才能对组件的class生效。
CSS Modules

转载于:https://juejin.im/post/5b8e43c5f265da43741e2e85

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值