React + antd怎么上传图片

#1

使用antd的form,怎么实现ajax上传图片功能?

1 Like
#2

不清楚,我是使用的react-dropzone + superagent实现的异步上传。
写一段简单的,你参考下

import Dropzone from 'react-dropzone';
import request from 'superagent';

dom

<Dropzone
                style={styles.imagesSelectItem}
                onDrop={this.handleFileSelectOnDrop.bind(this)}
                accept={'image/*'}
                multiple={false}
              >
                <img style={styles.imagesSelectImgNodeStyle} src={TS.IMG_ROOT + 'send/add_images.png'} />
              </Dropzone>
  handleFileSelectOnDrop(files) {
    let file = files[0];
    this.state.showEmoticon = false;

    if (!this.state.filenames.hasOwnProperty(file.name)) {
      this.state.filenames[file.name] = false;
      let data = {
        name: file.name,
        preview: file.preview,
        attach_id: 0,
      };
      let key = this.state.files.push(data);
      key -= 1;
      this.setState(this.state);

      request
        .post(buildURL('file', 'upload'))
        .attach(file.name, file)
        .end((error, Response) => {
          if (error || Response.status !== 200) {
            this.state.Snackbar.open = true;
            this.state.Snackbar.message = '上传失败!';
            delete this.state.filenames[file.name];
            delete this.state.files[key];

          } else if (Response.body.status != 1) {
            this.state.Snackbar.open = true;
            this.state.Snackbar.message = Response.body.message;
            delete this.state.filenames[file.name];
            delete this.state.files[key];

          } else if (Response.body.attach_id > 0) {
            data.attach_id = Response.body.attach_id;
            this.state.filenames[file.name] = true;

          } else {
            delete this.state.filenames[file.name];
            delete this.state.files[key];
          }
          this.setState(this.state);
        })
      ;
    } else {
      this.state.Snackbar.open = true;
      this.state.Snackbar.message = '请勿重复选择照片!';
      this.setState(this.state);
    }
  }

对你应该有帮助吧~

#3

上传图片,一般会需要服务器端支持,毕竟图片都要存起来的。我这里举个例子,是用node在服务端来处理 从用户端传过来的图片。

在antd里有相关包装好的组件,用Upload来实现上传,它有个属性叫action,跟form标签的action属性类似。action即表单要提交的处理页地址,我简要的写下关键位置如下:

<!-- ...-->
<Upload name="files" action="/upload" listType="picture"
  onChange={e=>this.handleUpload(e)}>
  <Button type="ghost">
    <Icon type="upload" /> 点击上传
  </Button>
</Upload>
<a href={this.state.projectImage} target="_blank" className="upload-example">
  <img src={this.state.projectImage} />
  <span>缩略图</span>
</a>
<!-- ...-->

如上述代码,我写了两个标签,一个Upload、一个a标签:Upload用于上传,a标签用于显示上传成功的图片。

先说这个Upload组件,我们把它看作一个 input[type="file"]标签。
当前的地址栏为“http://localhost:3005/manage/work/1”,它的action为 " /upload",意思相当于提交到“http://localhost:3005/upload”这个页,那这时候就轮到服务器出场了。

作为一个不想去依赖后端的 、又喜欢装B的前端攻城狮,我们自己动手去搭个服务器环境,费九牛二虎之力终于搭了一个基于express的node服务器。具体怎么搭建可以去搜搜express、node,或者感兴趣找我,之后再写写。

服务器端响应前端发的这个POST请求,http://localhost:3005/upload这一页来处理图片,包括获取数据流、重命名、保存到服务器端等等。

var express = require('express');
var fs = require('fs');
var path = require('path');
var multipart = require('connect-multiparty');
var router = express.Router();

/* GET App home page. */
router.get('*', function (req, res) {
  res.sendFile(path.resolve('./', 'index.html'));
});

router.post('/upload', multipart(), function (req, res) {
  //获得文件名
  var filename = req.files.files.originalFilename || path.basename(req.files.files.path);

  //复制文件到指定路径
  var targetPath = './public/uploads/' + filename;

  //复制文件流
  fs.createReadStream(req.files.files.path).pipe(fs.createWriteStream(targetPath));

  //响应ajax请求,告诉它图片传到哪了
  res.json({ code: 200, data: { url: 'http://' + req.headers.host + '/public/uploads/' + filename } });
});

这里服务器端就准备好了,就像两个小孩传球一样,“啊,我准备好了,你丢吧”。
点击这个Upload标签、选择图片、确定,然后开始了,上传。

这时我们看,Upload上有个事件函数 handleUpload()
我们来看看这个函数怎么定义的

//...
class ManageWork extends React.Component {
//...
  handleUpload(e) {
    if (e.file.status === 'done') {
      this.setState({ projectImage: e.file.response.data.url })
    }
  }
//...

我们看到了这个函数,当文件状态为done的时候,就意味着上传完成,这是调用this.setState()函数来设置this.state.projectImage的值,就是图片的url。

然后a标签里的img就能把这个图片显示出来了

有个demo项目可以看看,放github上的一个9000y,域名是briefguo.com

前后端全套学习视频分享(Java,react,vue)
#4

写的很详细,感谢