ant design 上传组件使用总结(手动上传)

最近使用到了 ant design 上传组件,用到了手动上传这部分,折腾了两三天,最后勉强摸通了手动上传的一些门路,记录一下。

手动上传显示缩略图

手动上传的预览选择 缩略图预览 的时候,会发现上传成功后,缩略图会消失,变成一个 svg 图标,像下面这样:


上传完成后缩略图消失

而自动上传是可以做到上传后保留缩略图的。原因大概是因为手动上传对beforeUpload return false,使 Upload 组件无法再触发组件上的 onChange事件,uploadList 组件上的 previewFile无法再次触发,导致 fileList 更新时无属性存储缩略图,导致缩略图丢失:

// antd/libs/upload/UploadList.js
var previewFile = function previewFile(file, callback) {
    var reader = new FileReader();
    reader.onloadend = function () {
        return callback(reader.result);
    };
    reader.readAsDataURL(file);
};

// previewFile 的调用
previewFile(file.originFileObj, function (previewDataUrl) {
   file.thumbUrl = previewDataUrl;
   _this2.forceUpdate();
});

可以发现,缩略图的显示方法是利用 FileReaderreadAsDataURLFile对象转为 base64,赋值给File对象thumbUrl属性,组件读到这个属性作为<img`>src的值从而显示缩略图。

那么,我们只要在代码中手动做一次文件的 base64 转换即可:

beforeUpload = (file) => {
    const r = new FileReader();
    r.readAsDataURL(file);
    r.onload = e => {
      file.thumbUrl = e.target.result;
      this.setState(state => ({
        fileList: [...state.fileList, file],
      }));
    };
    return false;
  }

将 base64 同样存储在 file 的 thumbUrl 属性中,就可以在文件上传成功后仍然显示缩略图。

手动上传文件后改变上传列表样式

自动上传在上传完成后,失败和成功都会有样式的改变,如:


文件上传失败

如果手动上传同样同样在失败成功后都没有样式上的改变。
要解决这个问题,还是要继续借鉴自动上传的经验,看看组件的源码。

翻看源码会发现,上传后的样式取决于filestatus属性,组件会根据不同的值给文件不同的样式,如果 file.statuserror,则会应用error相关的样式,如:

var infoUploadingClass = (0, _classnames2['default'])((_classNames = {},
  (0, _defineProperty3['default'])(_classNames, prefixCls + '-list-item', true),
  (0, _defineProperty3['default'])(_classNames, prefixCls + '-list-item-' + file.status, true), 
  _classNames
));
.ant-upload-list-picture-card .ant-upload-list-item-error,
.ant-upload-list-picture .ant-upload-list-item-error {
    border-color: #f5222d
}

说实话第一段代码我看不太懂,两个括号连在一起,有懂的同学还望赐教。

总之,就是根据 file.status去拼出一个类名来应用样式,这就好办了,只要在文件传输完成后,给 file.status设一个值就好了。
在自动上传中,上传完成后组件会对 fileList 做处理,自动添加 file.status属性,但是因为手动上传对beforeUpload返回了false,导致组件无法再对 fileList进行操作,所以就要我们在业务代码里自己添加了。

手动上传显示进度

UploadList 组件中关于显示进度的代码在这里:

if (file.status === 'uploading') {
  // show loading icon if upload progress listener is disabled
  var loadingProgress = 'percent' in file ? React.createElement(_progress2['default'], (0, _extends3['default'])({
    type: 'line'
  }, _this3.props.progressAttr, {
    percent: file.percent
  })) : null;
  progress = React.createElement(
    'div', {
      className: prefixCls + '-list-item-progress',
      key: 'progress'
    },
    loadingProgress
  );
}

读取file.percent,根据percent去控制样式,关于文件上传的进度,因为我使用的是 axios,所以在 axios 的 onUploadProgress中去读取进度并修改 fileList 即可:

axios({
  method: 'post',
  url: `${action}/${uploadTypeNum}`,
  data: e.target.result,
  onUploadProgress: progressEvent => {
    const complete = (progressEvent.loaded / progressEvent.total * 100 | 0);
    file.percent = complete;
    // this.ref 是上传组件
    this.ref.onChange({ file, fileList: this.state.fileList, });
  },
})

注意:以上对 file添加属性值,并不需要每次都执行setState,只要执行 Upload 组件的 onChange,将file, fileList传入即可


2019.1.22 更新:

之前我使用了 this.ref.onChange 去改变 UploadList 的状态,后来发现,可以不手动改变 UploadList 的状态。方法就是将 state 里的 fileList 传入 Upload组件中:

render() {
  const { fileList, } = this.state;
  return (
    <Upload fileList={fileList} />
  )
}

文件状态发生改变后改变 fileList即可:

fileList.forEach((file) => {
  const r = new FileReader();
  r.readAsArrayBuffer(file);
  r.onload = e => {
    file.status = 'uploading';
    this.setState({
      fileList,
    });
    axios({
        method: 'post',
        url: `${action}/${uploadTypeNum}`,
        data: e.target.result,
        onUploadProgress: progressEvent => {
          const complete = (progressEvent.loaded / progressEvent.total * 100 | 0);
          file.percent = complete;
          this.setState({
            fileList,
          });
        },
      })
      .then(res => {
        if (res.status === 200 && res.data.state === 'success') {
          file.status = 'success';
          file.code = res.data.code;
          this.setState((state) => ({
            uploading: false,
          }));
          this.setState({
            fileList,
          });
        } else {
          this.setState({
            uploading: false,
          });
          file.status = 'error';
          this.setState({
            fileList,
          });
          message.error(`${file.name}上传失败`);
        }
      })
      .catch(() => {
        this.setState({
          uploading: false,
        });
        message.error(`${file.name}上传失败了`);
        file.status = 'error';
        this.setState({
          fileList,
        });
      });
  };
});

参考文章:
ant design Upload组件的使用总结。 - 知乎
Upload manually cann't trigger Upload's onChange / 手动上传无法触发 Upload 组件的 onChange 事件 -- github issue

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容