Upload 文件上传

文件选择上传和拖拽上传控件。

何时使用#

上传是将信息(网页、文字、图片、视频等)通过网页或者上传工具发布到远程服务器上的过程。

  • 当需要上传一个或一些文件时。
  • 当需要展现上传的进度时。
  • 当需要使用拖拽交互时。

API#

参数 说明 类型 默认值
name 可选参数, 上传的文件 String file
action 必选参数, 上传的地址 String
data 可选参数, 上传所需参数 Object
headers 可选参数, 设置上传的请求头部,IE10 以上有效 Object
showUploadList 可选参数, 是否展示 uploadList, 默认开启 Boolean true
multiple 可选参数, 是否支持多选文件,ie10+ 支持。开启后按住 ctrl 可选择多个文件。 Boolean false
accept 可选参数, 接受上传的文件类型, 详见 input accept Attribute String
beforeUpload 可选参数, 上传文件之前的钩子,参数为上传的文件,若返回 false 或者 Promise 则停止上传。注意:该方法不支持老 IE Function
onChange 可选参数, 上传文件改变时的状态,详见 onChange Function
listType 上传列表的内建样式,支持两种基本样式 text or picture String 'text'
className 自定义类名 String

onChange#

文件状态改变的回调,返回为:

{
  file: { ... },
  fileList: [ ... ],
  event: { ... }
}
  1. file 当前操作的文件对象。

    {
      uid: 'uid',      // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突
      name: 'xx.png'   // 文件名
      status: 'done',  // 状态有:uploading done error removed
      response: '{"status":"success"}'  // 服务端响应内容
    }

    如果上传控件是 multiple 时,此参数将为一个对象数组 [file, ...]

  2. fileList 当前的文件列表。

  3. event 上传中的服务端响应内容,包含了上传进度等信息,高级浏览器支持。

显示下载链接#

请使用 fileList 属性设置数组项的 url 属性进行展示控制。

IE note#

代码演示

import { Upload, message, Button, Icon } from 'antd';

const props = {
  name: 'file',
  action: '/upload.do',
  onChange(info) {
    if (info.file.status !== 'uploading') {
      console.log(info.file, info.fileList);
    }
    if (info.file.status === 'done') {
      message.success(`${info.file.name} 上传成功。`);
    } else if (info.file.status === 'error') {
      message.error(`${info.file.name} 上传失败。`);
    }
  }
};

ReactDOM.render(
  <Upload {...props}>
    <Button type="ghost">
      <Icon type="upload" /> 点击上传
    </Button>
  </Upload>
, mountNode);

经典款式,用户点击按钮弹出文件选择框。

import { Upload, Button, Icon } from 'antd';

const MyUpload = React.createClass({
  getInitialState() {
    return {
      fileList: [{
        uid: -1,
        name: 'xxx.png',
        status: 'done',
        url: 'http://www.baidu.com/xxx.png'
      }]
    };
  },
  handleChange(info) {
    let fileList = info.fileList;

    // 1. 上传列表数量的限制
    //    只显示最近上传的一个,旧的会被新的顶掉
    fileList = fileList.slice(-2);

    // 2. 读取远程路径并显示链接
    fileList = fileList.map((file) => {
      if (file.response) {
        // 组件会将 file.url 作为链接进行展示
        file.url = file.response.url;
      }
      return file;
    });

    // 3. 按照服务器返回信息筛选成功上传的文件
    fileList = fileList.filter((file) => {
      if (file.response) {
        return file.response.status === 'success';
      }
      return true;
    });

    this.setState({ fileList });
  },
  render() {
    const props = {
      action: '/upload.do',
      onChange: this.handleChange,
      multiple: true
    };
    return (
      <Upload {...props} fileList={this.state.fileList}>
        <Button type="ghost">
          <Icon type="upload" /> 点击上传
        </Button>
      </Upload>
    );
  }
});

ReactDOM.render(<MyUpload />, mountNode);

使用 fileList 对列表进行完全控制,可以实现各种自定义功能,以下演示三种情况:

1) 上传列表数量的限制。

2) 读取远程路径并显示链接。

3) 按照服务器返回信息筛选成功上传的文件。

import { Upload, Button, Icon } from 'antd';

const props = {
  action: '/upload.do',
  listType: 'picture',
  defaultFileList: [{
    uid: -1,
    name: 'xxx.png',
    status: 'done',
    url: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
    thumbUrl: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
  }, {
    uid: -2,
    name: 'yyy.png',
    status: 'done',
    url: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
    thumbUrl: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
  }]
};

ReactDOM.render(
<div>
  <Upload {...props}>
    <Button type="ghost">
      <Icon type="upload" /> 点击上传
    </Button>
  </Upload>
  <br />
  <br />
  <Upload {...props} className="upload-list-inline">
    <Button type="ghost">
      <Icon type="upload" /> 点击上传
    </Button>
  </Upload>
</div>
, mountNode);
/* 加几行样式将上传项变成平铺样式 */
.upload-list-inline .ant-upload-list-item {
  display: inline-block;
  width: 200px;
  margin-right: 8px;
}

上传文件为图片,可展示本地缩略图。

IE8/9 不支持浏览器本地缩略图展示(Ref),可以写 thumbUrl 属性来代替。

import { Upload, Icon } from 'antd';

const props = {
  action: '/upload.do',
  listType: 'picture-card',
  defaultFileList: [{
    uid: -1,
    name: 'xxx.png',
    status: 'done',
    url: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
    thumbUrl: 'https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png',
  }]
};

ReactDOM.render(
<div className="clearfix">
  <Upload {...props}>
    <Icon type="plus" />
    <div className="ant-upload-text">上传照片</div>
  </Upload>
  <a href="https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png" target="_blank" className="upload-example">
    <img src="https://os.alipayobjects.com/rmsportal/NDbkJhpzmLxtPhB.png" />
    <span>示例</span>
  </a>
</div>
, mountNode);
/* 配合样式可以做出上传按钮和示例效果 */
.ant-upload-select-picture-card i {
  font-size: 28px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  font-size: 12px;
  color: #666;
}

.upload-example {
  position: relative;
  display: inline-block;
  height: 96px;
  width: 96px;
  padding: 8px;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  vertical-align: top;
}

.upload-example img {
  height: 78px;
  width: 78px;
}

.upload-example:before {
  position: absolute;
  bottom: 8px;
  left: 8px;
  content: ' ';
  width: 78px;
  height: 24px;
  background-color: #808080;
  opacity: .8;
}

.upload-example span {
  position: absolute;
  bottom: 8px;
  left: 8px;
  width: 78px;
  height: 24px;
  color: #fff;
  line-height: 24px;
  text-align: center;
}

上传文件为图片,可展示本地缩略图。

import { Upload, Button, Icon } from 'antd';

const props = {
  action: '/upload.do',
  onChange(info) {
    if (info.file.status !== 'uploading') {
      console.log(info.file);
      console.log(info.fileList);
    }
  },
  defaultFileList: [{
    uid: -1,
    name: 'xxx.png',
    status: 'done',
    url: 'http://www.baidu.com/xxx.png'
  }, {
    uid: -2,
    name: 'yyy.png',
    status: 'done',
    url: 'http://www.baidu.com/yyy.png'
  }]
};

ReactDOM.render(
  <Upload {...props}>
    <Button type="ghost">
      <Icon type="upload" /> 点击上传
    </Button>
  </Upload>
, mountNode);

对已上传的文件进行编辑。

import { Upload, Icon } from 'antd';
const Dragger = Upload.Dragger;

const props = {
  name: 'file',
  showUploadList: false,
  action: '/upload.do',
};

ReactDOM.render(
<div>
  <div style={{ width: 246, height: 140 }}>
    <Dragger {...props}>
      <Icon type="plus" />
    </Dragger>
  </div>
  <div style={{ marginTop: 16, height: 180 }}>
    <Dragger {...props}>
      <p className="ant-upload-drag-icon">
        <Icon type="inbox" />
      </p>
      <p className="ant-upload-text">点击或将文件拖拽到此区域上传</p>
      <p className="ant-upload-hint">支持单个或批量上传,严禁上传公司内部资料及其他违禁文件</p>
    </Dragger>
  </div>
</div>
, mountNode);

可以把文件拖入指定区域,完成上传,同样支持点击上传。

import { Upload, Button, Icon, message } from 'antd';

const props = {
  action: '/upload.do',
  beforeUpload(file) {
    const isJPG = file.type === 'image/jpeg';
    if (!isJPG) {
      message.error('只能上传 JPG 文件哦!');
    }
    return isJPG;
  }
};

ReactDOM.render(
  <Upload {...props}>
    <Button type="ghost">
      <Icon type="upload" /> 点击上传
    </Button>
  </Upload>
, mountNode);

可以通过 beforeUpload 在文件上传之前进行干预,如限制用户只能上传 JPG 文件。