一、产品需求
用户可以自由选择(选择后可以删除、重新选)一个文件,文件选择好后点击上传按钮进行上传。
二、代码实现
1.state定义
this.state = {
showModal: false,
fileList: [], //文件列表,用于控制upload组件
uploading: false //上传按钮loading显示控制
}
2.Upload组件的文件选择变化处理,上传按钮动作处理(使用axios上传文件)
handleFileChange = ({file, fileList}) => { //处理文件change,保证用户选择的文件只有一个
this.setState({
'fileList': fileList.length? [fileList[fileList.length - 1]] : []
})
}
handleUpload = () => {
if(!this.state.fileList.length) {
message.warning("请选择要上传的文件")
}
const formData = new FormData()
formData.append('file', this.state.fileList[0].originFileObj)
this.setState({
uploading: true
})
Axios.defaults.baseURL='https://jsonplaceholder.typicode.com/'
Axios({
method: 'post',
url: 'posts',
data: formData,
headers: { "Content-Type": "multipart/form-data"}
}).then(({data}) => {
message.success("上传成功")
console.log(data)
}).catch((err) =>{
console.log(err)
}).finally(() =>{
this.setState({
uploading: false
})
})
}
3.Upload组件使用
<Upload fileList={this.state.fileList} beforeUpload={(f, fList) => false} onChange={this.handleFileChange} >
<Button>
<CloudUploadOutlined /> 选择文件
</Button>
</Upload>
4.效果

三、注意事项
1.antd的Upload组件,在用户选择文件后会马上进行上传,可以自定义beforeUpload方法进行控制,若直接返回false就不上传“beforeUpload={(f, fList) => false}”。
2.要想post上传文件,发送的数据需要为FormData而不是json之类的,所以代码会先new一个FormData,然后把用户选择的文件添加到FormData里面去。(直接console.log打印FormData永远都是空,所以不要尝试直接打印FormData判断文件是否添加成功)
3.antd选择后的文件file是经过包装的数据,添加到formData时需要取file.originFileObj。官方案例没这么写,但用axios上传时如果直接使用file,后台会出现死活找不到数据的情况(坑了我好几个小时才找到原因)。
4.axios的请求参数中需要加入“headers: { "Content-Type": "multipart/form-data"}”,来申明传的是表单数据。