react中使用antd的upload组件,一个大坑比

先来看下大概实现的样子,

1、用本地的统一的缩列图

2、显示文件名字和大小

3、上传正常,编辑回显正常

 我看了下官网,确实是可以实现,大小和名字可以传个节点给到name这个属性,缩列图可以require个本地图片进去,然后上传好把他放在redux上绑定,但是会遇到好几个问题

1、每次上传好的数据发给后台东西一个fileList里面太多,只能把关键的字段塞进去

2、文件服务器失败的时候,form的校验居然通过了,就是要上传失败的时候主动清掉

3、回显的时候,redux里面有值,但是校验的时候又不通过了,要求我们判断redux有值主动setFieldsValue上去

来看一波大妈,

 <div className="modules modules-catalogProduct">
            <div className="module-title">产品介绍</div>
            <div className="open-attach-file-content">
              <Form.Item extra="文件类型:支持多种类型(doc、docx、xlx、xlsx、txt、pdf、jpg、png、ppt、MP4、wmv、MP3、zip) ">
                {getFieldDecorator('attachmentGoods')(
                  <Upload
                    action={uploadPath}
                    listType="picture"
                    fileList={catalogProductRelease.attachmentGoods}
                    onChange={this.handleUploadGoodsFileChange}
                    beforeUpload={this.handleAttachmentbeforeUpload}
                    className="upload-list-inline"
                  >
                    {catalogProductRelease.attachmentGoods.length < 5 ? (
                      <Button className="btn-upload">上传附件</Button>
                    ) : (
                      <Button disabled>上传附件</Button>
                    )}
                  </Upload>
                )}
              </Form.Item>
            </div>
          </div>

catalogProductRelease是model里的命名空间,props传进来,看下那几个函数怎么写的,

handleUploadGoodsFileChange = ({ file, fileList }) => {
    const { dispatch } = this.props
    if (file.status === 'error') {
      message.error('网络错误,请稍后重试')
      dispatch({
        type: 'catalogProductRelease/updateState',
        payload: { attachmentGoods: [] },
      })
    } else {
      const fileListFormat = fileList.map((imgItem, index) => ({
        uid: imgItem.uid,
        url: imgItem.url ? imgItem.url : imgItem.response || '',
        thumbUrl: require('../img/file_icon.png') || imgItem.response,
        name: imgItem.originFileObj
          ? this.renderFileListItemContent(
              imgItem.originFileObj.name,
              imgItem.size
            )
          : this.renderFileListItemContent(imgItem.fileName, imgItem.size),
        fileName: imgItem.originFileObj
          ? imgItem.originFileObj.name
          : imgItem.fileName,
        size: imgItem.size,
      }))
      dispatch({
        type: 'catalogProductRelease/updateState',
        payload: { attachmentGoods: fileListFormat },
      })
    }
  }
// 上传前
  handleAttachmentbeforeUpload = file => {
    const isLt20M = file.size / 1024 / 1024 < 20
    if (!isLt20M) {
      message.error('文件大小不能超过20M')
    }
    return new Promise((resolve, reject) => {
      if (!isLt20M) {
        reject(file)
      } else {
        resolve(file)
      }
    })
  }

 // 基本信息模块
  renderFileListItemContent = (name, size) => {
    return (
      <div title={name}>
        <span className="pic-content-title">{name}</span>
        <span className="pic-content-size">{`${(size / 1024 / 1024).toFixed(
          2
        )}M`}</span>
      </div>
    )
  }

基本信息模块就是把名字和大小拼起来,传入到name那里去,上传前的操作就不用多说了把,在第一个函数那里,当返回状态为error的时候主动清掉,成功的话拼成对应的字段存起来,一定要有uid,不然显示不出来。

接下来就是回显的时候,点击修改提交的时候,表单校验的问题啦,

if (
        catalogProductRelease.attachmentGoods.length > 0 &&
        !this.props.form.getFieldValue('attachmentGoods')
      ) {
        this.props.form.setFieldsValue({
          attachmentGoods: catalogProductRelease.attachmentGoods,
        })
      }

先判断redux存在没和页面上是否存在,有的话,主动写入。还有样式问题我就不贴出来了,如果你刚好也用到upload这个组件无从下手,可以留言沟通,冲起来,胸弟们

发布了22 篇原创文章 · 获赞 26 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/feizhong_web/article/details/103137036