項目是用的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判斷