upload组件自定义customRequest方法3.x.x版本踩坑记录

2,524 阅读4分钟

介绍

江流儿是21届毕业生,是个热爱前端开发的好少年,喜欢收藏唯美壁纸与技术交流,此篇文章是江流的首秀,同时也作为笔记,不足之处还希望大佬指点出来,先放壁纸👇👇👇

3D»æ»­ Å®ÆÍ ÃÀÍÈ ºÚË¿ ¸ß¸úЬ Á½Î»Å®ÆÍ½øÃźóµÄһĻ 4k¶¯Âþ±ÚÖ½_±Ë°¶Í¼Íø.jpg (图片来源网络侵权请留言)

这次主要分享的内容是antd的upload组件,我想如果公司业务没有涉及到这个上传业务的话我也不会去阅读upload的源码,为什么阅读这个组件的源码呢?有办法么?业务需要自定义,那为什么做这个分享呢?江流儿这几天一直收集相关的资料,发现关于自定义上传的资料,能让我看懂的实在是少的可怜,有办法嘛?

src=http---b-ssl.duitang.com-uploads-item-201707-25-20170725091808_ENmW8.thumb.700_0.jpeg&refer=http---b-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg.jpeg 下面进入正题👇👇👇

customRequest提供的API

先上API

截屏2021-07-19 下午11.17.01.png

onError 参数

  1. err: 请求错误信息
  2. response: 请求响应,不支持 iframeUpload
  3. file: 上传文件

onSuccess 参数

  1. result: 响应体
  2. file: 上传文件
  3. xhr: xhr 标头,仅适用于支持 AJAX 上传的现代浏览器。从 2.4.0 开始

自定义请求

允许通过覆盖 AjaxUploader 中的默认行为进行高级自定义。提供您自己的 XMLHttpRequest 调用以与自定义后端进程交互或通过 aws-sdk-js 包与 AWS S3 服务交互。

customRequest 回调传递一个对象:

  • onProgress: (event: { percent: number }): void
  • onError: (event: Error, body?: Object): void
  • onSuccess: (body: Object): void
  • data: Object
  • filename: String
  • file: File
  • withCredentials: Boolean
  • action: String
  • headers: Object 以上是源码提供的材料👆👆👆

这几个操作方法有几个值得注意的:

  1. onProgress方法:获取进度的方法,但是这个进度每次调用只返回一个百分比,配合antd的Progress组件的话需要自己转化一下
  2. file:这个是你要上传的文件,但是相比较antd已经封装好的会提供一个fileList(受控的),而file是一个对象,所以想要通过遍历的方式创建一个自定义的下载列表,需要包装
  3. onSuccess:上传成功的回调,在这里可以执行自己上传后想要处理的逻辑,下面代码是结合antd的全局提醒,当然你可以写更复杂的逻辑

customRequest例子

这里废话不多说,直接代码+注释

/* eslint-disable no-self-compare */

import React, { useState } from 'react'

import { Upload, Button, List,message } from 'antd'

import axios from 'axios'

const Myupload = () => {

const [fileList, setFileList] = useState([])

const uploadconfig = {

action: '',//必填的url

multiple: false,//是否允许一次上传多个文件

headers: {

Authorization: '$prefix $token',//请求头

},

onStart(file) {//这是这个函数开始执行时的打印传入的文件

console.log('onStart', file, file.status);

},

onSuccess(res, file) {//上传成功的回调函数

console.log('onSuccess', res, file.name);

message.success(`${file.name}上传成功`)

},

onError(err) {//上传出错的回调函数

console.log('onError', err);

message.error(`上传失败`)

},

onProgress({ percent }, file) {//axios提供的获取进度(注意:此处有坑,江流儿尚未解决)
//再次回调函数中可以获取到进度,但是想要更新进度条就要在此函数中赋值,就会出现下面描述的bug
console.log('onProgress', `${percent}%`, file.name);

setFileList([{name:file.name,percent:parseInt(percent),uid:file.uid}])
//在这里可以看到是给fileList赋值了的,但是这里只允许上传一个文件,如果上传多个,就会出现bug
//bug:如果上传多个,会出现自定义下载列表的闪烁问题
//(这个问题江流儿也没有解决,希望有大佬指点迷津)
},

onRemove:() => delPackage,//删除的回调

customRequest({

action,

file,

filename,

headers,

onError,

onProgress,

onSuccess,

withCredentials,

}) {

// EXAMPLE: post form-data with 'axios'

// eslint-disable-next-line no-undef

const formData = new FormData();

formData.append(filename, file);

var CancelToken = axios.CancelToken;//拿到中断请求的方法

var source = CancelToken.source();//同上

axios

.post(action, formData, {

withCredentials,

headers,

onUploadProgress: ({ total, loaded }) => {

onProgress({ percent: Math.round((loaded / total) * 100).toFixed(2) }, file);

},

})

.then(({ data: response }) => {

onSuccess(response, file);

})

.catch(onError);

return {

abort() {

console.log('终止函数');//此处的函数仅仅是一个函数,而当你创建axios实例时,你会发现根本没有abort方法(应该是我的问题吧)
//想要定义终止函数需要以下代码👇
             source.cancel()
//为什么不用老的方法呢?是因为axios也变了,有办法么?没有办法。谁让我迭代了个老项目呢(入世太浅,努力学习)
},

};

},

};

const delPackage = (file,index) => {
//...你的自定义删除逻辑
}

const { Item } = List;

return <div>

<Upload {...uploadconfig} showUploadList={false}>

<Button type='primary'>点击上传</Button>

</Upload>

<List

itemLayout='vertical'

>

{

fileList.map((item,index) => {

return (<Item key={index}>

<div>{item.name}</div>

<div>进度:{item.percent}</div>

<div><Button onClick={() => { delPackage(item,index) }} type='primary'>删除</Button></div>

</Item>)

})

}

</List>

</div>

}

export default Myupload

上述代码可以完成的业务仅仅支撑本地上传单个文件,为什么没有讲上传多个文件呢?因为我也不会,等我研究出来在更,如果有大佬能看出我的忧伤~^_^,请帮帮孩子,如果有遇到此类问题的朋友,欢迎留言交流。

江流儿寄语(不是很重要,选择性阅读):江流儿觉得,如果你能把文章看到这里了,就给江流儿一个赞吧,江流儿也努力成为一个高质量文章输出者,替更多的人解决问题,一路自学过来,就好像很火的一句话,“自己淋过雨,所以想为他人撑把伞吧。”欢迎想学前端,但是迷茫的小伙伴咨询哦😁

感谢阅读哦