antd 封装拖拽上传图片组件+粘贴自动上传

2023-09-23 晚上前端 32 次浏览暂无评论

拖拽

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>
  );
}

目录

ICP备案号:鲁ICP备2020040322号