iview 的upload组件可能一些api和属性会有一些变化,但大体类似
官网给出的示例,其主要应用场景为通过设置action(文件上传url),单独上传文件,官网给出的相关方法和属性都是基于设置action单独上传文件实现的。但有时候我们的需求是上传表单数据和文件列表到一个接口而不是设置action单独上传文件,这时候官网给出的例子可能就不能直接使用,需要一定的改变,本篇文章就是基于这样的前端需求产生的。以下为官网给出的示例:
import { Upload, message, Button } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
const props = {
name: 'file',
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
headers: {
authorization: 'authorization-text',
},
onChange(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
message.success(`${info.file.name} file uploaded successfully`);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
},
};
ReactDOM.render(
<Upload {...props}>
<Button icon={<UploadOutlined />}>Click to Upload</Button>
</Upload>,
mountNode,
);
// upload组件使用
import { Button, Form, Upload, message } from "antd";
import { UploadOutlined } from "@ant-design/icons";
import {
upload,
} from "@/api/upload.js"; //引入上传的接口
import { useState, useEffect} from "react";
/*定义允许上传的文件后缀*/
const filePostfix =
"'jpg', 'jpeg', 'png','bmp','svg','gif', 'doc','docx', 'xls', 'xlsx', 'ppt','pptx','pdf'";
function Upload() {
const [form] = Form.useForm();
//上传文件列表
const [fileList, setFileList] = useState([]);
// 文件上传预处理事件
const beforeUploadHandler = (file) => {
let splitByDot = file.name.split(".");
//取最后一个“.”后的内容:1.1.jpg
let postfix = splitByDot[splitByDot.length - 1];
const check = fileList.length < 10;
// 控制上传文件类型
if (!check) {
message.warning("最多上传十个文件");
} else {
if (filePostfix.indexOf(postfix) > -1) {
fileList.push(file);
} else {
message.warning(
"文件格式不正确: 仅支持图片、word、ppt、excel类型的文件!"
);
}
}
return false;
};
// 删除文件处理事件
const handleRemove = (file) => {
let idx = fileList.indexOf(file);
let arr = [];
for (let i = 0; i < fileList.length; i++) {
arr[i] = fileList[i];
}
while (idx !== fileList.length - 1) {
arr[idx] = fileList[idx + 1];
idx++;
}
if (idx == fileList.length - 1) {
arr.pop();
}
setFileList(arr);
return true;
};
const onFinish = (val) => {
console.log("success");
console.log(val);
};
const onFinishFailed = (errInfo) => {
console.log(errInfo);
};
const upload = () => {
let params = form.getFieldValue();
let uploadParams = { ...params };
uploadFiles(uploadParams );
};
const uploadFiles= (params) => {
let formData = new FormData();
fileList.forEach((file, index) => {
// multipartFiles为上传的文件参数名
formData.append("multipartFiles", file);
});
let reqParams = {
//具体请求参数根据接口要求改变
method: "post",
params: {
...params, // 其他表单参数
},
data: formData,
};
upload(reqParams)
.then((res) => {
if (res.data.code == 200) {
message.success(res.data.message);
form.resetFields(); // 表单数据清空
setFileList([]); // 文件列表清空
} else {
message.error(res.data.message);
}
})
.catch((error) => {
console.log(error);
});
};
const clear = () => {
form.resetFields();
};
return (
<div>
<Form
form={form}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
labelAlign="right"
labelWrap={true}
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
>
<Form.Item>
<div>
<Upload
action=""
accept={filePostfix}
multiple
fileList={fileList}
beforeUpload={beforeUploadHandler}
showUploadList={true}
onRemove={handleRemove}
>
<Button
icon={<UploadOutlined />}
className={dongdongStyles.upload}
>
点击上传
</Button>
</Upload>
</div>
</Form.Item>
<Form.Item>
<div style={{ marginBottom: "10px" }}>
<Button type="primary" onClick={upload}>
提交
</Button>
<Button onClick={clear} style={{ marginLeft: "5px" }}>
重置
</Button>
</div>
</Form.Item>
</Form>
</div>
);
}
export default Upload;
axios上传文件对应参考博客:
点击删除文件图标后,文件列表删除了该文件,但下方上传文件列表处仍显示该文件,刷新文件删除:
这块之前是直接更新fileList的值,而非通过setFileList方法更新fileList的值,所以,fileList值变了但当前状态下fileList的值还是原先的值,所以删除的文件列表仍存在,这里应该通过setFileList更新fileList的值。
正确代码如下:
// 删除文件处理事件
const handleRemove = (file) => {
let idx = fileList.indexOf(file);
let arr = [];
for (let i = 0; i < fileList.length; i++) {
arr[i] = fileList[i];
}
while (idx !== fileList.length - 1) {
arr[idx] = fileList[idx + 1];
idx++;
}
if (idx == fileList.length - 1) {
arr.pop();
}
setFileList(arr);
return true;
};
详见axios请求