项目是用的react hook写的,引入了antd 的upload上传组件,页面效果如下
代码
import React, { useState } from 'react' import { Modal, Form, Upload, message, Button } from 'antd' import { UploadOutlined } from '@ant-design/icons' import { TableListItem } from '@/services/data.d' import { importByExcelUrl } from '@/services/manually' import { validFileSize } from '@/utils/validate' export interface FormValueType extends Partial<TableListItem> { time?: string; [propName: string]: any } const FormItem = Form.Item interface CreateFormProps { modalVisible: boolean; onCancel: () => void; onConfirm: (values: FormValueType) => void; values: any } const formLayout = { labelCol: { span: 7 }, wrapperCol: { span: 13 }, } const UploadForm: React.FC<CreateFormProps> = (props) => { const { modalVisible, onConfirm, onCancel } = props const [bussinessFileList, setFilelist] = useState<any[]>([]) const [uploadFileList, setUploadFilelist] = useState<any[]>([]) const [form] = Form.useForm() form.setFieldsValue({}) const uploadprops = { name: 'file', action: importByExcelUrl(), headers: { authorization: 'authorization-text', }, accept: '.csv,.xls,.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel', data: { businessCode: props.values }, disabled: bussinessFileList.length === 1, fileList: uploadFileList, beforeUpload(file: any) { // console.log(6, file, uploadFileList.length, validFileSize(file)) if (uploadFileList.length > 0) { message.warning('只能上传一个文件') return false } if (file.size === 0) { message.error('文件不能为空') return false } return validFileSize(file) }, onChange(info: any) { let files: any[] = [...info.fileList] if (info.file.status === 'done') { if (info.file.response) { if (info.file.response.responseCode === '000000') { // files = [...info.fileList] message.success(`${info.file.name} 文件上传成功`) } else { message.error(info.file.response.responseMsg) } } else { message.error(`${info.file.name} 上传失败.`) } } else if (info.file.status === 'error') { message.error(`${info.file.name} 上传失败.`) } files = files.filter((item : any) => { return item.response?.responseCode === '000000' }) files = JSON.parse(JSON.stringify(files)) console.log(66666, info, files) setUploadFilelist(files) setFilelist(files) }, } const renderContent = () => { return ( <> <FormItem name='uploads' label='上传模板' required rules={[{ validator: (rule, value, callback) => { if (value && value.fileList && value.fileList.length) { console.log(77, value) if (value.file.response && value.file.response.responseCode === '000000') { callback() } else if (value.file.status && value.file.status === 'uploading') { callback() } else { callback('文件信息有误,请删除后上传正确文件') } } else callback('请选择文件上传') } }]} > <Upload {...uploadprops}> <Button> <UploadOutlined /> 点击上传 </Button> </Upload> </FormItem> </> ) } const handleConfirm = async() => { const fieldsValue = await form.validateFields() // console.log(fieldsValue) onConfirm(fieldsValue) } return ( <Modal destroyOnClose title='上传模板' visible={modalVisible} onOk={() => handleConfirm()} maskClosable={false} onCancel={() => onCancel()} > <Form {...formLayout} form={form} initialValues={{}} > {renderContent()} </Form> </Modal> ) } export default UploadForm
想做到的效果是用户文件上传正确,才展示在页面上,上传错误不展示在页面上.使用了upload的fileList属性,发现文件上传状态一直是uploading
在官网找了一圈答案https://github.com/ant-design/ant-design/issues/2423这个issue里有问题描述,试了里面的一些方法还是不起作用
后面发现实际问题是,fileList这个属性不能设置为空数组
这里已经说得很明白了,所以说想用这个属性来控制文件,就必须保证不会为空数组,但是这个跟我的需求不符,所以后来没用这个属性,是用form的rules来提示客户删除不正确的文件重新上传
但是如果一定要实现这个功能可以自己写fileList
<FormItem name='uploads' label='上传模板' required rules={[{ validator: (rule, value, callback) => { if (value && value.fileList && value.fileList.length) { console.log(77, value) if (value.file.response && value.file.response.responseCode === '000000') { callback() } else if (value.file.status && value.file.status === 'uploading') { callback() } else { callback('文件信息有误,请删除后上传正确文件') } } else callback('请选择文件上传') } }]} > <> <Upload {...uploadprops} showUploadList={false}> <Button> <UploadOutlined /> 点击上传 </Button> </Upload> {bussinessFileList.length ? <ul> // 大概的就是这样,具体样式自己要调整一下 {bussinessFileList.map(item => <li key={item.uid}> {item.name} </li>)} </ul> : null} </> </FormItem>
这样写要注意一个问题,formtien默认值会获取内部的一个闭合标签的值,这里加了列表之后,form rules里面的value将会获取不到file上传的内容,可以换成bussinessFileList判断