antd 封装拖拽上传图片组件+粘贴自动上传
拖拽
import { getOssPolicy } from "@/services";
import { InboxOutlined } from "@ant-design/icons";
import { uuidv4 } from "uuid";
import { UploadFile, UploadProps } from "antd";
import Dragger from "antd/lib/upload/Dragger";
import _ from "lodash";
import { useEffect, useState } from "react";
import { useQuery } from "react-query";
type Props = {
value?: Array<string>;
onChange?: (value: Array<string>) => void;
};
export default function UploadImage({ value, onChange }: Props) {
// 文件列表
const [fileList, setFileList] = useState<UploadFile[]>([]);
// 获取oss信息
const { data: ossPolicy } = useQuery(getOssPolicy.name, () => {
return getOssPolicy({
path: "upload/",
bucked_host: "https://dajxstatic.oss-cn-beijing.aliyuncs.com",
});
});
// 初始化文件列表
useEffect(() => {
const initList: any = _.map(value, (item) => ({ url: item, id: item }));
setFileList(initList);
}, []);
// 文件列表改变时,改变表单数据,改变文件列表
const handleChange: UploadProps["onChange"] = ({ file, fileList: newFileList }) => {
setFileList(newFileList);
if (_.every(newFileList, (item) => item.status === "done")) {
const imgs = _.map(fileList, (i: any) =>
i.fileName ? `https://static.daanjiexi.com/upload/${i.fileName}` : i.name
);
onChange?.(imgs);
}
};
return (
<div>
<Dragger
action={ossPolicy?.host}
name="file"
key="Image-Upload"
accept="image/png, image/jpeg"
listType="picture-card"
fileList={fileList}
multiple={true}
showUploadList={true}
onChange={handleChange}
data={(file) => {
file.fileName = `${uuidv4()}.${file.name.split(".").pop()}`;
return {
key: `upload/${file.fileName}`,
policy: ossPolicy.policy,
signature: ossPolicy.signature,
OSSAccessKeyId: ossPolicy.accessid,
success_action_status: "200",
};
}}
>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">点击或者拖拽文件来添加图片</p>
</Dragger>
</div>
);
}
使用
<UploadImage
value={showImgList}
onChange={(value: string[]) => {
if (!value) return;
console.log("newvalue", value);
setShowImgList(value);
}}
/>
粘贴图片
useEffect(() => {
const handPaste = async (event: any) => {
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
const imgs = _.filter(items, (item) => item.type.indexOf("image") !== -1);
const imgUrls = _.map(imgs, async (item) => {
const fromData = new FormData();
fromData.append("file", item.getAsFile());
return uploadStaticOss(fromData).then((res) => res.value);
});
const urls = await Promise.all(imgUrls);
setShowImgList((prev) => {
return [...prev, ...urls];
});
toggleShowImg(true);
};
document.addEventListener("paste", handPaste);
return () => {
document.removeEventListener("paste", handPaste);
};
}, []);
点击上传,和拖拽基本一致,改下antd组件类型即可
import { getOssPolicy } from "@/services";
import { InboxOutlined, PlusOutlined } from "@ant-design/icons";
import { uuidv4 } from "amis";
import { Upload, UploadFile, UploadProps } from "antd";
import Dragger from "antd/lib/upload/Dragger";
import _ from "lodash";
import { useEffect, useState } from "react";
import { useQuery } from "react-query";
type Props = {
value?: Array<string>;
onChange?: (value: Array<string>) => void;
};
export default function UploadImage({ value, onChange }: Props) {
// 文件列表
const [fileList, setFileList] = useState<UploadFile[]>([]);
// 获取oss信息
const { data: ossPolicy } = useQuery(getOssPolicy.name, () => {
return getOssPolicy({
path: "upload/",
bucked_host: "https://dajxstatic.oss-cn-beijing.aliyuncs.com",
});
});
// 初始化文件列表
useEffect(() => {
const initList: any = _.map(value, (item) => ({ url: item, id: item }));
setFileList(initList);
}, [value]);
// 文件列表改变时,改变表单数据,改变文件列表
const handleChange: UploadProps["onChange"] = ({ file, fileList: newFileList }) => {
setFileList(newFileList);
if (_.every(newFileList, (item) => item.status === "done")) {
const imgs = _.map(fileList, (i: any) =>
i.fileName ? `https://static.daanjiexi.com/upload/${i.fileName}` : i.name
);
onChange?.(imgs);
}
};
return (
<div>
<Upload
action={ossPolicy?.host}
name="file"
key="Image-Upload"
accept="image/png, image/jpeg"
listType="picture-card"
fileList={fileList}
multiple={true}
showUploadList={true}
onChange={handleChange}
data={(file) => {
file.fileName = `${uuidv4()}.${file.name.split(".").pop()}`;
return {
key: `upload/${file.fileName}`,
policy: ossPolicy.policy,
signature: ossPolicy.signature,
OSSAccessKeyId: ossPolicy.accessid,
success_action_status: "200",
};
}}
>
<div className="text-2xl">
<PlusOutlined />
</div>
</Upload>
</div>
);
}