Ant Design Pro 组件踩坑记录

ProFormUploadButton 踩坑记录

最近在用ant design pro 组件做项目,在使用到ProFormUploadButton这个组件的时候,发现很多文档上没有写的东西,接下来把我的踩坑记录分享给大家.

刚开始只有一个上传的需求,我就把官网的示例直接copy了下来,如下:
 
后面跟我说要一个预览的功能,这样其我就参考ant design 的组件加成这样:
 {handleChange(e)},}}fileList={fileList}extra="只能上传jpg/png文件,且不大于3MB"/> 
测试后,发现没有前置校验,于是加了前置校验,如下:
// 上传前置校验
const beforeUpload = (file: RcFile) => {const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';if (!isJpgOrPng) {message.error('只允许上传 JPG/PNG 格式的文件');}const isLt3M = file.size / 1024 / 1024 < 3;if (!isLt3M) {message.error('仅支持3M以下的文件');}return isJpgOrPng && isLt3M}; 
测试后,发现就算校验了,会自动跳过,还是会调接口,所以改成这样
// 上传前置校验
const beforeUpload = (file: RcFile) => {const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';if (!isJpgOrPng) {message.error('只允许上传 JPG/PNG 格式的文件');}const isLt3M = file.size / 1024 / 1024 < 3;if (!isLt3M) {message.error('仅支持3M以下的文件');}// 如果返回了if ((isJpgOrPng && isLt3M) === false) {// 在这里记得要清空fileList// 返回这个参数beforeUpload为false就可以拦截住了return Upload.LIST_IGNORE} else {return true}}; 

注意:除了fileList以外, 其他所有的属性都要放到ProFormUploadButton组件的fieldProps里面,这样才能生效.

注意二: 在onchange方法里如果上传文件状态为error,还是会显示到fileList,这时候要处理一下:

if (info.file.status == 'error') {message.error('上传失败!请稍后再试')setFileList([])} 
我以为到这里就结束了,没想到,又加了需求,说是要让图片可以旋转,放大缩小,我网上找了个js库,用的人比较多,鉴于我是react, 所以又找了个用react封装的插件,下面贴一下两个库的git地址.

react版本 tinymins/viewerjs-react: React wrapper for viewerjs. (github.com)

原版 fengyuanchen/viewerjs: JavaScript image viewer. (github.com)

贴一下整页的代码,方便自己以后回看.
import type { UploadProps } from 'antd';
import { Card, Col, Row, message, Button, Upload, Modal } from 'antd';
import type { FC} from 'react';
import { useState, useEffect, useRef } from 'react';
import type {ProFormInstance} from '@ant-design/pro-form';

import ProForm, {ProFormText,ProFormSelect,ProFormDependency,ProFormRadio,ProFormDatePicker,ProFormUploadButton
} from '@ant-design/pro-form';
import { PageContainer } from '@ant-design/pro-layout';
import styles from './style.less';
import { getCompanyInfoApi, saveCompanyInfoApi } from './service';
import { validatorOnlyCn, validatorPhoneAndFixedPro, validatorCerdit, validatorEnName, businessLicenseDeadLine } from '@/utils/validator';
import type { UploadChangeParam } from 'antd/lib/upload';
import type { RcFile, UploadFile } from 'antd/lib/upload/interface';
import { history } from 'umi';
import moment from 'moment';
// import ImageFunc from '@/components/ImageFunc';
import RViewerJS from 'viewerjs-react'
import 'viewerjs-react/dist/index.css'
interface TableFormDateType {key: string;workId?: string;name?: string;department?: string;isNew?: boolean;editable?: boolean;
}
const getBase64 = (file: RcFile): Promise =>new Promise((resolve, reject) => {const reader = new FileReader();reader.readAsDataURL(file);reader.onload = () => resolve(reader.result as string);reader.onerror = error => reject(error);});

const FormAdvancedForm: FC> = () => {const [id, setId] = useState('');// 绑定一个 ProFormInstance 实例const formRef = useRef>();const [imageName, setImageName] = useState();const [imageUrl, setImageUrl] = useState();const [fileList, setFileList] = useState<[]>();const [btnLoading, setbtnLoading] = useState(false);// 为false时不校验格式const [noVer, setNoVer] = useState(true);const set_image_url = (new_data) => {setImageUrl(new_data)}const handlePreview = async (file: UploadFile) => {if (!file.url && !file.preview) {file.preview = await getBase64(file.originFileObj as RcFile);}setImageUrl(file.url || (file.preview as string));setImageName(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1));setTimeout(() => { document.getElementById('imgpre').click()}, 0)};const getCompanyInfoFunc =() => {setFileList(null)getCompanyInfoApi({loginName: sessionStorage.getItem('loginName') || ''}).then((res: any) => {if (res.code === 200) {// 表单回显// 拷贝一份数据const newData = JSON.parse(JSON.stringify(res.data))// businessLicense需要的是list格式的数据 如果不删掉会报错delete newData.businessLicense// 表单回显formRef.current?.setFieldsValue(newData)// 做成fileList的格式传回const flit = [{uid: moment().valueOf(),name: res.data.businessLicenseName,status: 'done',url: res.data.businessLicense}]if (res.data.businessLicense) {// 回显fileListformRef.current?.setFieldsValue({businessLicense: flit})setFileList(flit)set_image_url(res.data.businessLicense)setImageName(res.data.businessLicenseName)}// res.data.id为null表示是新增if (res.data.id === null) {setId('')return;} else {setId(res.data.id)}// 不为null表示是编辑return;}message.error('查询失败!请稍后再试') })}const onFinish = async (values: Record) => {setbtnLoading(true)delete values.fileconst obj = {id: id === '' ? undefined : id,code: sessionStorage.getItem('loginName'),businessLicense: imageUrl,businessLicenseName: imageName}// eslint-disable-next-line @typescript-eslint/no-unused-expressionsvalues.name ? delete values.name : ''// eslint-disable-next-line @typescript-eslint/no-unused-expressionsvalues.tel ? delete values.tel : ''// eslint-disable-next-line @typescript-eslint/no-unused-expressionsvalues.code ? delete values.code : ''// eslint-disable-next-line @typescript-eslint/no-unused-expressionsvalues.email ? delete values.email : ''values.businessLicenseDeadLine = values.businessLicenseDeadLine ? moment(moment(values.businessLicenseDeadLine).format('YYYY-MM-DD') + ' 23:59:59').valueOf() : undefinedtry {await saveCompanyInfoApi({...values,...obj}).then(res => {setbtnLoading(false)if (res.code !== 200) {message.error('提交失败,请稍后再试');return;}message.success('提交成功'); // 在这里更改组件是否刷新的flagsessionStorage.setItem('destroyInactiveTabPane', 'true')getCompanyInfoFunc()history.push('/platform/filingReview/certification');})} catch {message.error('提交出错,请稍后再试');setbtnLoading(false)}};useEffect(() => {// 在这里更改组件是否刷新的flagsessionStorage.setItem('destroyInactiveTabPane', 'true')getCompanyInfoFunc()}, []);
 const beforeUpload = (file: RcFile) => {const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';if (!isJpgOrPng) {message.error('只允许上传 JPG/PNG 格式的文件');}const isLt3M = file.size / 1024 / 1024 < 3;if (!isLt3M) {message.error('仅支持3M以下的文件');}if ((isJpgOrPng && isLt3M) === false) {setFileList(null)setImageName(undefined)set_image_url(undefined);formRef.current?.resetFields(['resetFields'])return Upload.LIST_IGNORE} else {return true}};const handleChange: UploadProps['onChange'] = (info: UploadChangeParam) => { if (info.file.status == 'removed') {setFileList(null)}if (info.file.status === 'done') {// Get this url from response in real world.// 做成fileList的格式传回if (info.file.response.code !== 200) {message.error(info.file.response.msg)return;}let obj ={uid: moment().valueOf(),name: info.file.response.data.fileName,status: 'done',url: info.file.response.data.filePath}setFileList([obj])setImageName(info.file.response.data.fileName)set_image_url(info.file.response.data.filePath);return;}if (info.file.status == 'error') {message.error('上传失败!请稍后再试')setFileList([])}};// 点击删除的时候直接清空fileListconst onRemove = () => {setFileList(null)}//选择认证失败时 进行的操作const failFunC = () => {setNoVer(false) } return (
layout="horizontal"// 通过formRef进行绑定formRef={formRef}onFinish={onFinish}submitter={{// 配置按钮文本searchConfig: {submitText: '提交',},// 配置按钮的属性resetButtonProps: {style: {// 隐藏重置按钮display: 'none',},},// 完全自定义整个区域render: (props, doms) => {return [];},}}labelCol={{span: 10}}> {/* 公司类型 */} {/* 营业执照期限 */}{({ businessLicenseStatus }) => {if (businessLicenseStatus === '长期') {return ('');}return;}} {return beforeUpload(e)},onRemove,headers: {'timestamp': (new Date().valueOf()) + ''},onChange: (e) => {handleChange(e)},onPreview: handlePreview,}}fileList={fileList}// previewFile={() => {}}extra="只能上传jpg/png文件,且不大于3MB"/>{/* 页面不显示这个组件 点击预览的时候模拟点击这个组件 效果是一样的 */} {({ certificationStatus }) => {if (certificationStatus !== 3) {setNoVer(true)formRef.current?.resetFields(['certificationRemark'])return ('');} else {failFunC()}return ;}}
); }; export default FormAdvancedForm;

你可能感兴趣的:(前端,javascript,react.js)