通过覆盖默认的上传行为,可以自定义自己的上传实现
自定义的上传步骤
调用预上传接口拿到上传地址与对象存储id
使用put方法上传文件并带上存储id
// 定义变量与方法, 方便描述
const PRE_UPLOAD_URL // 预上传地址
const UPLOAD_URL // 上传地址
const objectID // 对象存储id
const parseSearchString // 格式化url参数为对象的方法
const toSearchString // 格式化对象为url参数的方法
const getUrlByObjectID // 通过对象存储id拿url的方法
const uuid // 生成唯一id的方法
const Uploader = ({ onChange, value, children, ...props }) => {
// 初始化初始值
useEffect(() => {
if (!value) return;
const fileList = value.map((fileInfo) => {
const { name, objectID, } = fileInfo
const uid = uuid()
return {
status: "done", // 初始值文件的状态
url: getUrlByObjectID(fileInfo.objectID), // 获取显示图片的url
uid, // 内部唯一id
name, // 文件名称
objectID
}
});
// 更新
onChange && onChange(fileList);
}, []);
return (
<Upload
action={(file) => {
return new Promise((c, e) => {
// 请求预上传地址,拿到上传地址与id
axios.get(PRE_UPLOAD_URL).then(
(res) => {
const data = res.data;
const { UPLOAD_URL, objectID } = data;
const [base, queryStr] = UPLOAD_URL.split("?");
const query = {
objectID, // 把id通过query的方式传递
...parseSearchString(queryStr),
};
c(`${base}${toSearchString(query)}`);
},
() => {
e("上传失败");
},
);
});
}}
customRequest={(e) => {
const [url, queryStr] = e.action.split("?");
const query = parseSearchString(queryStr);
// 取出对象存储id
const { objectID = "", ...other } = query;
const file = e.file;
const name = file.name; // 文件名字
组装上传地址
const action = `${url}${toSearchString(other)}`;
axios
.put(action, file, {
// 显示进度
onUploadProgress: (ev) => {
const percent = ((ev.loaded / ev.total) * 100) | 0;
e.onProgress(
{
percent,
},
file,
);
},
})
.then(
() => {
const url = getUrlByObjectID(objectID)
// 上传成功
e.onSuccess(
{
objectID,
name,
url,
},
file,
);
},
(res) => {
e.onError(res);
},
);
}}
onChange={({ event, fileList }) => {
if (event && event.percent === 100) {
// 这里100%后不能正常拿到上传的对象 需要延迟处理
setTimeout(() => {
// 上面onSuccess传递的参数会被包裹在response中
let value = fileList.map(({ response, uid }) => ({ ...response, uid }));
onChange && onChange(value);
}, 1000);
}
}}
method="put"
{...props}
/>
);
};
在form中使用
<Form.Item name="upload" label="上传图片">
<Uploader listType="picture">
<Button>
<UploadOutlined /> 上传图标
</Button>
</Uploader>
</Form.Item>