自定义文件上传组件
前提:
本来是可以用ant Design的Upload组件完成文件上传的,但由于需要把文件和其他表单信息一起传递给后台,所以放弃了使用蚂蚁现成的Upload组件,使用Input组件改造.
html部分:
<Input
type="file" id="upload-file"
multiple accept=".xls,.xlsx"
onchange={(e)=>{e.persist();
/*e.target.files就是上传的文件的信息*/
}}/>
因为只能上传Excel文档,所以我使用accep属性进行了现在.提示:网上有大佬指出这里应该填写application/vtn...一长串的东西,我试了一下,没有用,还是这种文件后缀名有效. multiple表示可以选择多个文件.
js部分:
export async function add({file, url}) {
const finalUrl = url;
const formData = new FormData();
formData.append('file', file, file.name);
return fetch(finalUrl, {
method: 'POST',
body: formData,
}).then((response) => {
return response
}) .catch((err) => {
console.log('出错啦')
return { err };
});
}
export async function add({ url, file }) { const finalUrl = url; const formData = new FormData(); formData.append('file', file, file.name); fetch(finalUrl, { method: 'POST', body: formData, }) .then( (res) => { return res.json() }) .then((data) => {//data为上一个then方法return的值 console.log(data) return data }) .catch(err => { console.log(err) })
//return 'hello world'}
由于fetch请求是一个异步请求,所以fetch以及后面的then和catch都会放在微任务队列中.由于catch后面没有同步的return语句,所以调用这个方法获得的就是undefined.假设把注释掉的那句return代码打开,那调用add方法的函数会得到'hello world'字符串.
为了能够将获取到的结果返回给调用add方法的函数,则应该在该add方法中使用await,才能把请求后的结果返回给调用者.
export async function add({ url, file }) {
const finalUrl = url;
const formData = new FormData();
formData.append('file', file, file.name);
const response = await fetch(finalUrl, {
method: 'POST',
body: formData,
});
return await response.json()
}
这里又涉及到了异步的问题.谈到异步肯定会想到promise和async/await.
Promise和async/await的比较:
一般有异步的地方,任务队列肯定少不了.至此,再谈下事件循环的问题.
css部分:
如果直接这么做,样式非常丑,并且按钮中的文字只能是"选择文件",有时候产品的需求是"导入文件"之类的.
<a
href="javascript:;"
style={{
padding: 4,color: '#000', borderWith: 1, borderStyle: 'solid', borderColor: '#ddd', borderRadius: 4}}
> <Input
type="file"
style={{lineHeight: 1.3,position: 'absolute',left: 0, right: 0, top: 0, opacity: 0}}
id="uploadUid"
accept=".xlsx,.xls"
onChange={(e) => {
e.persist();//关于input框的onchange事件获取不到e.target的问题只需要在赋值前加上 e.persist() 即可
this.setState({fileList: [e.target.files[0].name]})}}/>
<span>{fileList.length > 0 ? "重新导入": '导入文件'}</span>
</a>
<span>{fileList.length == 0 ? '未选择文件' : '文件名'}</span>
这样改造后,上传文件的组件的按钮中的文字也可以随心所欲地修改,并且也会像原生那样显示文件名,在没有选择文件的时候显示"未选择文件"的提示信息.
fetch请求资源
Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了,参数有点像jQuery ajax。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。
fetch跨网络异步获取资源
跨域
fetch与Ajax,axios的区别
axios是对原生XHR的封装
promise, async/await
XMLHttpRequest
JSON() blog.csdn.net/zty5556666/…
如果有不正确的地方,欢迎指正.如果有更好的解决方案,感谢分享!
总结:自定义文件上传组件其实还是非常地简单,只是前期自己不断地摸索会花费很多时间,但在摸索的过程中自己能够学到更多的知识.