记一笔之:antd 的 Upload 上传组件 uploadin

2019-08-02  本文已影响0人  文艺的小唐

相信用 Upload 的很多老兄都遇到过这个问题,就是在处理上传文件时,从 onchange 方法中得到的 e.fileList 里面的 status 参数他么总是 uploading ,而不是我们需要的 done 状态,导致拿不到 thumbUrl 和 response 的 imgUrl 。
根据官网文档上对 这个问题 的解释,就是要注意两点:

 this.setState({ fileList: [...this.state.fileList] })

不过对于以上第二点,个人亲测,即使直接 { fileList: e.fileList } 就可以。以下假定只传一张图片,一个完整的 onchange 事件内部处理可以像下面一样:

handleChange = e => {
    if (e.file.status == 'done') {
      if (e.file.response.code === 200) {
        let result = e.fileList;
        result[0].thumbUrl = result[0].response.imgUrl; //用绝对路径替代base64,有助于在保存图片的时候避免字段过长和减小数据库的压力
        this.setState({ fileList: result });
      } else {
        Modal.warn({
          title: '提示',
          content: <span>{e.file.response.msg}</span>,
          okText: 'ok',
        });
      }
    }
    this.setState({ fileList: e.fileList });
  };

对应的react DOM结构可以是:

          <FormItem label="上传图片">
                {this.props.form.getFieldDecorator('file', { rules: [{ required: true, message: '请上传图片' }] })(
                    <div>
                      <Upload
                        name="file"
                        multiple={false}
                        headers={{ Accept: 'application/json', token: getToken() }}
                        action={this.state.imgUploadUrl}
                        listType="picture-card"
                        fileList={this.state.fileList}
                        onPreview={this.handlePreview}
                        onChange={this.handleChange}
                        accept="image/jpg, image/png"
                      >
                        {this.state.fileList.length >= 1 ? null : <div><Icon type="plus" /><div className="ant-upload-text">上传</div></div>}
                      </Upload>
                      <Modal visible={this.state.previewVisible} footer={null} onCancel={this.handleCancel}>
                        <img alt="example" style={{ width: '100%' }} src={this.state.previewImage} />
                      </Modal>
                    </div>
                )}
              </FormItem>

如上DOM结构,在一些常规操作中,上传图片的操作,很可能会存在这样的场景:新建记录、更新记录、获取记录详情、保存记录等等,同时配合使用 Form 以及 Form.Item 组件,以及 getFieldValue、setFieldValue、getFieldDecorator 等等 api 使 Upload 的操作受控。在使用 Upload 组件时,也许需要注意以下几点:

          this.setState({
              previewImage: url,
              fileList: [ {
                  thumbUrl: url,
                  status: 'done',    // 这个必须,不然,图片自然显示不出来
                  uid: url,      // 这个随意吧
              } ],
            });
      // 以及将受控字段的值设为 url:
        this.props.form.setFieldsValue( { file: bannerUrl } )
handleAddSubmit = () => {
    const { form: { validateFields, setFieldsValue } } = this.props;
    const { fileList } = this.state;
    if (!fileList.length) {
      // 编辑图片时候,如果删掉缩略图,fileList会被清空,不过 getFieldsValue 获取file 的值还在,这时候提交无errors,但是fileList是空的
      setFieldsValue({ file: undefined });
    }
    validateFields((errors, values) => {
      if (!errors) {
        let data = {
          url: fileList[0].thumbUrl,
        }
       // 以下做你的骚操作。。。
     }
 }
图片1.png

以上代码有一句注释,说啥意思呢?意思就是,我们在编辑图片的时候,可能想把图片换一张,就删掉了,然而,这个时候打了一秒钟瞌睡,醒来就搞忘了,就直接点提交。这个时候呢,本来 Form 组件在使用 getFieldDecorator 时,已经设置必填了,然而图片这个时候虽然看似删掉了,因为以上示例图片处已经变成一个上传提示按钮了,但是提交事件虽然没有提示以上 errors错误,但是 thumbUrl 却报错 undefined 了?这特么就尴尬了。
这啥原因呢?原因就是 validateFields 的函数参数 的values 参数中,file 字段的值(就是被删掉的图片的地址)并没有随着点击示例图上删除那样,把 file 字段的值重置,删除图片的操作只是把 fileList 状态重置清空了。这个时候提交结果是,Form.Item 处并没有 必填的错误提示,validateFields 通过了必填验证,然而,fileList 早已经变成了空数组。this.props.form.getFieldValue('file') 也就是上一张图的路径却还在。
所以,在操作这种情况时,要判断 fileList 是否为空,如果为空表示图片已经被删除,那么同时将 file 的状态同步一下,做了这个操作后,validateFields 验证空图片的时候,就会有错误提示“请上传图片”。

上一篇 下一篇

猜你喜欢

热点阅读