react使用antd实现手动上传文件(提交表单)

前言:最近在做一个后台管理项目涉及到上传文件,使用antd里的Upload实现上传文件。记录一下遇到的问题和坑。

1.要实现的效果

我要实现的效果就是点击上传文件,选择完文件后点击ok(也就是提交表单后在上传)其实就是手动上传文件。下面我来介绍一下我的做法和我遇到的一些坑。

2.实现步骤

1.引入所需antd的部件

import { Table, Button, Modal, Form, Input, Upload, Icon, notification } from 'antd';

这个时表单的 

 <Modal
          title="文件上传"
          visible={this.state.visible}
          onOk={this.handleOk} //点击按钮提价表单并上传文件
          onCancel={this.handleCancel}
        >
          <Form layout="vertical" onSubmit={this.handleSubmit}>
            <Form.Item>
              <div  key={Math.random()}>//点击关闭在次打开还会有上次上传文件的缓存
                <Upload {...props}>
                  <Button type="primary">
                    <Icon type="upload" />选择文件
                 </Button>
                </Upload>

              </div>
            </Form.Item>
            <Form.Item label="文件名(可更改)">
              {getFieldDecorator('filename', {
                // initialValue:this.state.defEmail,
                rules: [
                  {
                    message: '请输入正确的文件名',
                    // pattern: /^[0-9]+$/,
                  },
                  {
                    required: true,
                    message: '请输入文件名',
                  },
                ],
              })(<Input />)}
            </Form.Item>
            <Form.Item label="描述(选填)">
              {getFieldDecorator('describe', {

                rules: [
                  {
                    message: '描述不能为空',
                  },
                  {
                    required: false,
                    message: '请输入描述',
                  },
                ],
              })(<TextArea />)}
            </Form.Item>
            <Form.Item label="文件类型">
              {getFieldDecorator('filetype', {
                rules: [
                  {
                    message: '文件类型',
                  },
                  {
                    required: true,
                    message: '文件类型',
                  },
                ],
              })(<Input disabled={true} />)}
            </Form.Item>
          </Form>
        </Modal>

下面的代码时Upload的props,只需要把beforeUpload 返回 false 后,手动上传文件。

    const props = {
      showUploadList: true,
      onRemove: file => {
        this.setState(state => {
          const index = state.fileList.indexOf(file);
          const newFileList = state.fileList.slice();
          newFileList.splice(index, 1);
          return {
            fileList: newFileList,
          };
        });
      },
      beforeUpload: file => {
        console.log(file)
        let { name } = file;
        var fileExtension = name.substring(name.lastIndexOf('.') + 1);//截取文件后缀名
        this.props.form.setFieldsValue({ 'filename': name, 'filetype': fileExtension });//选择完文件后把文件名和后缀名自动填入表单
        this.setState(state => ({
          fileList: [...state.fileList, file],
        }));
        return false;
      },
      fileList,
    };

下面是重点提交表单并上传文件

handleOk = e => {//点击ok确认上传
    const { fileList } = this.state;
    let formData = new FormData();
    fileList.forEach(file => {
      formData.append('file', file);
    });

    this.props.form.validateFields((err, values) => { //获取表单值
      let { filename, filetype, describe } = values;
      formData.append('name', filename);
      formData.append('type', filetype);
      formData.append("dir", "1");
      if(describe==undefined){
        formData.append('description',"");
      }else{
        formData.append('description',describe);
      }
      
      UploadFile(formData).then(res => { //这个是请求
        if (res.status == 200 && res.data != undefined) {
          notification.success({
            message: "上传成功",
            description: res.data,
          });
        } else {
          notification.error({
            message: "上传失败",
            description: res.status,
          });
        }
      })
      this.setState({
        visible: false
      });

    })
  };

注意我用的axios,post必须使用formData.append("接口参数名",“要传的值”);如果不想用axios还可以用别的请求

fetch(url, { //fetch请求
        method: 'POST',
        body: formData,
    })






      axios({ //axios
        method: 'post',
        url: url,
        data: formData,
        headers:{ //可加可不加
          'Content-Type': 'multipart/form-data; boundary=---- 
           WebKitFormBoundary6jwpHyBuz5iALV7b'
        }
    })
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    });

这样就能实现手动上传文件了。

antd 3.x官网示例:

上传 Upload - Ant Design-手动上传

antd 4.x 官网示例:

上传 Upload - Ant Design-手动上传 

antd 5.x官网示例:

上传 Upload - Ant Design-手动上传

3.遇到的坑

第一次选择完文件,点击上传。第二次在打开Model发现上回的文件列表还在,我在网上找的方法是给upload及一个key值但只有点击ok后第二次打开Model缓存才会消失,但是点击canel还会存在。

<div key={Math.random()}>
                <Upload  {...props}>
                  <Button type="primary">
                    <Icon type="upload" />选择文件
                 </Button>
                </Upload>

              </div>

最好的方法就是this.setState把state里文件列表置空

 this.props.form.resetFields()//添加之前把input值清空
    this.setState({
      visible: true,
      fileList: [] //把文件列表清空
    });

也可以给Modal加一个 destroyOnClose 属性  关闭时销毁 Modal 里的子元素 

upload用法可参考antd官网

antd v4 -手动上传 官网示例

  • 7
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
好的,下面是一个简单的示例代码: 首先安装所需依赖: ```bash npm install react antd axios --save ``` 然后创建一个 `Login` 组件和一个 `Register` 组件,分别用于登录和注册的页面展示。其中,我们使用了 `Form` 和 `Input` 组件来实现表单输入,以及 `Button` 组件来实现按钮的功能。 ```jsx // Login.jsx import React, { useState } from 'react'; import { Form, Input, Button, message } from 'antd'; import axios from 'axios'; const Login = () => { const [loading, setLoading] = useState(false); const onFinish = async (values) => { setLoading(true); try { const response = await axios.post('/api/login', values); message.success(response.data.message); setLoading(false); } catch (error) { message.error(error.response.data.message); setLoading(false); } }; return ( <Form name="login" onFinish={onFinish}> <Form.Item name="email" rules={[{ required: true, message: 'Please input your email!' }]} > <Input placeholder="Email" /> </Form.Item> <Form.Item name="password" rules={[{ required: true, message: 'Please input your password!' }]} > <Input.Password placeholder="Password" /> </Form.Item> <Form.Item> <Button type="primary" htmlType="submit" loading={loading}> Login </Button> </Form.Item> </Form> ); }; export default Login; ``` ```jsx // Register.jsx import React, { useState } from 'react'; import { Form, Input, Button, message } from 'antd'; import axios from 'axios'; const Register = () => { const [loading, setLoading] = useState(false); const onFinish = async (values) => { setLoading(true); try { const response = await axios.post('/api/register', values); message.success(response.data.message); setLoading(false); } catch (error) { message.error(error.response.data.message); setLoading(false); } }; return ( <Form name="register" onFinish={onFinish}> <Form.Item name="name" rules={[{ required: true, message: 'Please input your name!' }]} > <Input placeholder="Name" /> </Form.Item> <Form.Item name="email" rules={[{ required: true, message: 'Please input your email!' }]} > <Input placeholder="Email" /> </Form.Item> <Form.Item name="password" rules={[{ required: true, message: 'Please input your password!' }]} > <Input.Password placeholder="Password" /> </Form.Item> <Form.Item name="confirmPassword" rules={[ { required: true, message: 'Please confirm your password!' }, ({ getFieldValue }) => ({ validator(_, value) { if (!value || getFieldValue('password') === value) { return Promise.resolve(); } return Promise.reject(new Error('The two passwords do not match!')); }, }), ]} > <Input.Password placeholder="Confirm Password" /> </Form.Item> <Form.Item> <Button type="primary" htmlType="submit" loading={loading}> Register </Button> </Form.Item> </Form> ); }; export default Register; ``` 在这里我们使用了 `axios` 来发送登录和注册的请求,需要注意的是,这里的请求地址是 `/api/login` 和 `/api/register`,而不是实际的后端接口地址,根据实际情况进行修改。 最后在需要展示登录和注册功能的页面中引入 `Login` 和 `Register` 组件即可。 ```jsx import React from 'react'; import Login from './Login'; import Register from './Register'; const LoginPage = () => { return ( <div> <h1>Login</h1> <Login /> <hr /> <h1>Register</h1> <Register /> </div> ); }; export default LoginPage; ``` 以上就是一个简单的使用 `react` 和 `antd` 实现登录和注册功能的示例代码,希望对你有帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

崽崽的谷雨

漫漫前端路,摸爬滚打

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值