antd上传组件upload踩坑和封装

效果图:

1、公共组件封装:

将antd中的上传组件进行改进:

不同文件格式使用不同上传样式;

增加上传限制:大小,数量,尺寸;

UploadCustom.js

import { PlusOutlined, UploadOutlined } from '@ant-design/icons';
import { Button, message, Modal, Upload } from 'antd';
import Axios from 'axios';
import bytes from 'bytes';
import dayjs from 'dayjs';
import React, { memo, useEffect, useState } from 'react';
import { getRandomIntInclusive } from '../../utils/utils';

function UploadOSS(props) {
  const {
    onChange,
    value,
    dirPath,
    listType,
    multiple,
    accept,
    limit,
    sizeLimit,
    className,
    width,
    height,
  } = props;
  const [uploadData, setUploadData] = useState({});
  let flag = false;

  // 初始化上传所需参数(从接口获取,过程省略)
  const init = async () => {
    setUploadData({});
  };

  useEffect(() => {
    init();
  }, [dirPath]);

  // 捕捉上传出错的文件
  const handleChange = ({ file, fileList }) => {
    if (file.status === 'error') {
      message.error('上传出错!');
    }
    if (onChange) {
      onChange(fileList.filter((v) => v.status === 'done' || v.status === 'uploading'));
    }
  };

  // 移除文件
  const onRemove = (file) => {
    const files = value.filter((v) => v.url !== file.url);
    if (onChange) {
      onChange(files);
    }
  };

  // 上传之前转换对象
  const transformFile = (file) => {
    const suffix = file.name.slice(file.name.lastIndexOf('.'));
    const filename = `${getRandomIntInclusive(1000, 9999)}-${dayjs().format(
      'YYYY-MM-DD',
    )}${Date.now()}${suffix}`;
    file.url = `${dirPath}${filename}`;
    return file;
  };

  // 上传所需额外参数
  const getExtraData = (file) => {
    return {
      key: file.url,
      success_action_status: 200,
      policy: uploadData.policy,
      Signature: uploadData.signature,
    };
  };

  // 图片尺寸比例限制
  const checkSize = (file) => {
    return new Promise((resolve, reject) => {
      const url = window.URL || window.webkitURL;
      const img = new Image();
      img.onload = () => {
        const valid =
          img.width >= width && img.height >= height && img.width / img.height === width / height;
        valid ? resolve() : reject();
      };
      img.src = url.createObjectURL(file);
    }).then(
      () => {
        return true;
      },
      () => {
        if (flag) {
          Modal.error({
            title: `图片尺寸不符合要求,请修改后重新上传!`,
          });
          flag = false;
        }
        return Promise.reject();
      },
    );
  };

  // 图片大小限制
  const checkLimit = (file) => {
    return new Promise((resolve, reject) => {
      file.size <= sizeLimit ? resolve() : reject();
    }).then(
      () => {
        return true;
      },
      () => {
        if (flag) {
          Modal.error({
            title: `超过大小限制${bytes(sizeLimit)},请重新选择!`,
          });
          flag = false;
        }
        return Promise.reject();
      },
    );
  };

  // 数量限制
  const checkLen = (fileList) => {
    return new Promise((resolve, reject) => {
      const isLen = value.length + fileList.length;
      isLen <= limit ? resolve() : reject();
    }).then(
      () => {
        return true;
      },
      () => {
        if (flag) {
          Modal.error({
            title: `超过最大上传数量${limit}张,请重新选择!`,
          });
          flag = false;
        }
        return Promise.reject();
      },
    );
  };

  // 判断所有条件满足才能上传
  const beforeUpload = async (file, fileList) => {
    flag = true;
    const isLen = limit ? await checkLen(fileList) : true;
    const isSizeLimit = sizeLimit ? await checkLimit(file) : true;
    const isSize = width ? await checkSize(file) : true;
    const expire = uploadData.expire * 1000;
    if (expire < Date.now()) {
      await init();
    }
    return isLen && isSizeLimit && isSize;
  };

  // 图片预览处理
  const handlePreview = async (file) => {
    let src = file.url;
    if (!src || src.indexOf('http') === -1) {
      src = await new Promise((resolve) => {
        const reader = new FileReader();
        reader.readAsDataURL(file.originFileObj);
        reader.onload = () => resolve(reader.result);
      });
    }
    const image = new Image();
    image.src = src;
    const imgWindow = window.open(src);
    imgWindow.document.write(image.outerHTML);
  };

  const uploadProps = {
    name: 'file',
    fileList: value,
    action: uploadData.host,
    onChange: handleChange,
    data: getExtraData,
    onPreview: handlePreview,
    onRemove,
    transformFile,
    beforeUpload,
    listType,
    multiple,
    accept,
    className,
  };

  // 文件和图片使用不同的样式
  const Con = () =>
    listType ? (
      <div>
        <PlusOutlined />
        <div className="ant-upload-text">上传</div>
      </div>
    ) : (
      <Button>
        <UploadOutlined /> 上传
      </Button>
    );

  return <Upload {...uploadProps}>{value && value.length < limit && Con()}</Upload>;
}

export default memo(UploadCustom);

使用组件:

index.js

import UploadCustom from '';


return (
  <>
    <UploadCustom
        dirPath="files/"
        limit={1}
        sizeLimit={bytes('2GB')}
        accept=".exe,.msi,.rar,.zip,.7z"
    ></UploadCustom>

    <UploadCustom
        dirPath="appstore/adp/logo/"
        listType="picture-card"
        accept="image/*"
        limit={1}
        sizeLimit={bytes('5MB')}
        className="upload-list-inline"
        width={256}
        height={256}
     ></UploadCustom>
  </>
)

 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
antd组件库的Upload组件上传文件后,如果还提示规则验证失败,可能是因为您设置了规则验证函数(rules)但是没有正确地处理上传文件的情况。您可以在规则验证函数中增加对上传文件的判断。例如,在上传图片时,您可以通过判断文件类型和文件大小来进行验证。具体的代码实现可以参考下面的示例: ```jsx <Form.Item name="avatar" label="Avatar" rules={[ { required: true, message: 'Please upload your avatar', }, ({ getFieldValue }) => ({ validator(_, file) { const maxSize = 2 * 1024 * 1024; // 2MB const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'; if (!isJPG) { return Promise.reject('You can only upload JPG/PNG file!'); } else if (file.size > maxSize) { return Promise.reject(`Image must smaller than ${maxSize / 1024 / 1024}MB!`); } else { return Promise.resolve(); } }, }), ]} valuePropName="fileList" getValueFromEvent={normFile} > <Upload name="avatar" action="/upload.do" listType="picture"> <Button icon={<UploadOutlined />}>Click to upload</Button> </Upload> </Form.Item> ``` 在这个示例中,我们设置了一个规则验证函数,它会验证上传的文件是否是JPG或PNG格式,以及文件大小是否小于2MB。如果验证失败,会返回一个Promise.reject(),提示错误信息。如果验证通过,会返回一个Promise.resolve(),表示验证成功。这样,在上传文件后,就会先进行规则验证,如果验证通过,才会提交表单数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值