antd form+upload把上传后的文件删除后,表单校验失效了

antd form+upload把上传后的文件删除后,表单校验失效了

const [file, setFile] = useState();
const [form] = Form.useForm();

const props: UploadProps = {
	name: 'file',
	showUploadList: true, //是否展示上传后的文件列表
	accept: '.bin,.tar,.gz,.zip',
	maxCount: 1, //最大上传文件数
	customRequest: async (options) => {
		//这里是我根据项目需求自定义的上传成功操作,小伙伴们可不管,但注意这里要设置file的内容,否则后面不管成功失败都会报错
		const { file, onSuccess, onProgress } = options;
		onProgress(file);
		const md5 = await getMD5(file);
		if (md5 === 'error') message.error('md5解析失败');
		getBase64(file, (url) => {
			let finalFile = {
				file,
				md5,
				size: file.size,
				content: url,
			};
			setFile(finalFile);//注意这里要设置file
			onSuccess(finalFile, undefined);
		});
	},
	onRemove: (file) => {
		setFile(null);
	},
};
<Form
	form={form}
	layout="horizontal"
	name="nest-messages"
	onFinish={onFinish}
	>
	<Form.Item
		name="file"
		label=“选择文件"
		rules={[
			{
				required: true,
				message: '必选',
			},
		]}
	>
		<Upload {...props}>
			<Button icon={<PlusOutlined />}>点击选择</Button>
			<span className="hint">
			仅支持 bin, tar, gz, zip 类型的文件,文件大小不能超过		1024MB
			</span>
		</Upload>
	</Form.Item>
</Form>

在提交之前再判断一下
我的表单提交是写在弹出框中的,

onRemove中将file置为空,这里提交前先判断一下file如果不在了就将form中的file表单域值也置为空

这里的setFieldsValue我试过直接写在onRemove中,本想在remove时就直接将表单项置空,但是结果提交时发现表单中file还是有值,所以需要在提交之前再判断一波

<Modal
	title="添加固件"
	visible={visible}
	onCancel={() => cancelModal('')}
	onOk={() => {
		//————关键———
		//onRemove中将file置为空,这里提交前先判断一下file如果不在了就将form中的file表单域值也置为空
		//这里的setFieldsValue我试过直接写在onRemove中,本想在remove时就直接将表单项置空,但是结果提交时发现表单中file还是有值,所以需要在提交之前再判断一波
		if (!file) {
			form.setFieldsValue({
			file: '',
			});
		}
		//————关键-------
		form.validateFields()
			.then(async (values) => {
				// 检验成功时;
				form.resetFields();
				form.setFieldsValue(values); // 例:{tagName:'888'}
				await okModal(values, file);
			})
			.catch((info) => {
				// 检验失败时;
				console.log('校验失败:', info);
			});
		}}
	>
		<Form ………………/>
	</Modal>

在弹出框中写表单的部分不是此次重点,所以省略,感兴趣的小伙伴可以去看我之前的文章
antd+ Umi使用中出现的问题集合(一)之 antd中Modal结合form的复合使用

最后来看一下最终效果吧
在这里插入图片描述

在这里插入图片描述
顺便附上全部代码

import {
  Form,
  Input,
  Modal,
  Upload,
  Button,
  message,
  Descriptions,
} from 'antd';
import { useEffect, useState } from 'react';
import { PlusOutlined } from '@ant-design/icons';
import type { UploadProps } from 'antd';
import { RcFile, UploadChangeParam, UploadFile } from 'antd/lib/upload';
import config from '@/config/dev';
import { uploadFile } from '@/api/file';
import { filterUnit, getMD5, transferSize } from '@/utils';

const API_URL = config.apiBase;
const token = localStorage.getItem('token');
export const AddUpgradeForm = (params: any) => {
  const { visible, cancelModal, okModal } = params;
  const [file, setFile] = useState<any>();
  const [form] = Form.useForm();

  useEffect(() => {
    form.resetFields();
    form.setFieldsValue({
      name: '',
      description: '',
      product: '',
      version: '',
    });
  }, []);

  const onFinish = async (values: any) => {};

  const props: UploadProps = {
    name: 'file',
    showUploadList: true,
    accept: '.bin,.tar,.gz,.zip',
    maxCount: 1,
    // beforeUpload: async (file) => {
    //   const md5 = await getMD5(file)
    //   if (md5 === 'error') message.error('md5解析失败');
    //   getBase64(file, url => {
    //     let finalFile = {
    //       file,
    //       md5,
    //       size: transferSize(file.size),
    //       content: url
    //     }
    //     setFile(finalFile);
    //   })
    // },
    customRequest: async (options) => {
      const { file, onSuccess, onProgress } = options;
      onProgress(file);
      const md5 = await getMD5(file);
      if (md5 === 'error') message.error('md5解析失败');
      getBase64(file, (url) => {
        let finalFile = {
          file,
          md5,
          size: file.size,
          content: url,
        };
        setFile(finalFile);
        onSuccess(finalFile, undefined);
      });
    },
    onRemove: (file) => {
      setFile(null);
    },
  };

  const getBase64 = (img: any, callback: (url: string) => void) => {
    const reader = new FileReader();
    reader.addEventListener('load', () => callback(reader.result as string));
    reader.readAsDataURL(img);
  };

  return (
    <Modal
      title="添加固件"
      visible={visible}
      onCancel={() => cancelModal('')}
      onOk={() => {
        if (!file) {
          form.setFieldsValue({
            file: '',
          });
        }
        form
          .validateFields()
          .then(async (values) => {
            // 检验成功时;
            form.resetFields();
            form.setFieldsValue(values); // 例:{tagName:'888'}
            await okModal(values, file);
          })
          .catch((info) => {
            // 检验失败时;
            console.log('校验失败:', info);
          });
      }}
    >
      <Form
        form={form}
        layout="horizontal"
        name="nest-messages"
        labelCol={{ span: 4 }}
        wrapperCol={{ span: 20 }}
        onFinish={onFinish}
      >
        <Form.Item
          name="name"
          label="固件名称"
          rules={[
            {
              required: true,
              message: '必填',
            },
          ]}
        >
          <Input />
        </Form.Item>
        <Form.Item
          name="version"
          label="固件版本"
          rules={[
            {
              required: true,
              message: '必填',
            },
            {
              pattern: /^[a-zA-Z0-9_\.-]{0,31}$/,
              message: '请填写正确格式',
            },
          ]}
        >
          <Input placeholder="仅支持英文字母、数字、点、中划线和下划线,长度限制1~32" />
        </Form.Item>
        <Form.Item
          name="product"
          label="产品名称"
          rules={[
            {
              required: true,
              message: '必填',
            },
          ]}
        >
          <Input />
        </Form.Item>
        <Form.Item name="description" label="固件描述" rules={[]}>
          <Input.TextArea rows={2} />
        </Form.Item>
        <Form.Item
          name="file"
          label="选择固件"
          rules={[
            {
              required: true,
              message: '固件必选',
            },
          ]}
        >
          <Upload {...props}>
            <Button icon={<PlusOutlined />}>点击选择固件</Button>
            <span className="hint">
              仅支持 bin, tar, gz, zip 类型的文件,文件大小不能超过1024MB
            </span>
          </Upload>
        </Form.Item>
        {file ? (
          <Form.Item
            style={{
              paddingLeft: '16%',
            }}
          >
            <Descriptions size="small" column={1}>
              <Descriptions.Item label="文件名">
                {file.file.name}
              </Descriptions.Item>
              <Descriptions.Item label="文件大小">
                {transferSize(file.file.size)}
              </Descriptions.Item>
              <Descriptions.Item label="md5">{file.md5}</Descriptions.Item>
            </Descriptions>
          </Form.Item>
        ) : null}
      </Form>
    </Modal>
  );
};

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ant Design 3.x 版本中,可以使用 `Form.create()` 方法创建一个高阶组件,将表单组件包裹起来,实现表单的数据绑定、校验等功能。 以下是使用 `Form.create()` 方法创建 Ant Design 3.x 版本的表单组件的示例代码: ```javascript import React, { useState } from 'react'; import { Form, Input, Button } from 'antd'; const FormItem = Form.Item; const ExampleForm = ({ form }) => { const { getFieldDecorator, validateFields } = form; const handleSubmit = (e) => { e.preventDefault(); validateFields((errors, values) => { if (!errors) { console.log(values); // 表单提交的数据 } }); }; return ( <Form onSubmit={handleSubmit}> <FormItem label="用户名"> {getFieldDecorator('username', { rules: [{ required: true, message: '请输入用户名' }], })(<Input placeholder="请输入用户名" />)} </FormItem> <FormItem label="密码"> {getFieldDecorator('password', { rules: [{ required: true, message: '请输入密码' }], })(<Input type="password" placeholder="请输入密码" />)} </FormItem> <FormItem> <Button type="primary" htmlType="submit">提交</Button> </FormItem> </Form> ); }; export default Form.create()(ExampleForm); ``` 上述代码中,通过 `Form.create()` 方法创建了一个高阶组件,并将表单组件 `ExampleForm` 作为参数传递给它,经过处理后返回一个新的包裹了表单组件的组件。 在表单组件中,使用 `getFieldDecorator` 方法包装表单控件,实现表单值的双向绑定和校验规则的设置。`validateFields` 方法用于表单数据校验,如果校验通过则将表单数据提交到后端。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值