• 上传
    • 何时使用
    • 代码演示
      • 点击上传
      • 用户头像
      • 已上传的文件列表
      • 照片墙
      • 完全控制的上传列表
      • 拖拽上传
      • 图片列表样式
      • 手动上传
      • 文件夹上传
  • API
    • 事件
    • change

    上传

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

    何时使用

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

    代码演示

    Upload上传 - 图1

    点击上传

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

    1. <template>
    2. <a-upload name="file" :multiple="true" action="//jsonplaceholder.typicode.com/posts/" :headers="headers" @change="handleChange">
    3. <a-button>
    4. <a-icon type="upload" /> Click to Upload
    5. </a-button>
    6. </a-upload>
    7. </template>
    8. <script>
    9. export default {
    10. data () {
    11. return {
    12. headers: {
    13. authorization: 'authorization-text',
    14. }
    15. }
    16. },
    17. methods: {
    18. handleChange(info) {
    19. if (info.file.status !== 'uploading') {
    20. console.log(info.file, info.fileList);
    21. }
    22. if (info.file.status === 'done') {
    23. this.$message.success(`${info.file.name} file uploaded successfully`);
    24. } else if (info.file.status === 'error') {
    25. this.$message.error(`${info.file.name} file upload failed.`);
    26. }
    27. },
    28. },
    29. }
    30. </script>

    Upload上传 - 图2

    用户头像

    点击上传用户头像,并使用 beforeUpload 限制用户上传的图片格式和大小。 beforeUpload 的返回值可以是一个 Promise 以支持异步处理,如服务端校验等

    1. <template>
    2. <a-upload
    3. name="avatar"
    4. listType="picture-card"
    5. class="avatar-uploader"
    6. :showUploadList="false"
    7. action="//jsonplaceholder.typicode.com/posts/"
    8. :beforeUpload="beforeUpload"
    9. @change="handleChange"
    10. >
    11. <img v-if="imageUrl" :src="imageUrl" alt="avatar" />
    12. <div v-else>
    13. <a-icon :type="loading ? 'loading' : 'plus'" />
    14. <div class="ant-upload-text">Upload</div>
    15. </div>
    16. </a-upload>
    17. </template>
    18. <script>
    19. function getBase64 (img, callback) {
    20. const reader = new FileReader()
    21. reader.addEventListener('load', () => callback(reader.result))
    22. reader.readAsDataURL(img)
    23. }
    24. export default {
    25. data () {
    26. return {
    27. loading: false,
    28. imageUrl: '',
    29. }
    30. },
    31. methods: {
    32. handleChange (info) {
    33. if (info.file.status === 'uploading') {
    34. this.loading = true
    35. return
    36. }
    37. if (info.file.status === 'done') {
    38. // Get this url from response in real world.
    39. getBase64(info.file.originFileObj, (imageUrl) => {
    40. this.imageUrl = imageUrl
    41. this.loading = false
    42. })
    43. }
    44. },
    45. beforeUpload (file) {
    46. const isJPG = file.type === 'image/jpeg'
    47. if (!isJPG) {
    48. this.$message.error('You can only upload JPG file!')
    49. }
    50. const isLt2M = file.size / 1024 / 1024 < 2
    51. if (!isLt2M) {
    52. this.$message.error('Image must smaller than 2MB!')
    53. }
    54. return isJPG && isLt2M
    55. },
    56. },
    57. }
    58. </script>
    59. <style>
    60. .avatar-uploader > .ant-upload {
    61. width: 128px;
    62. height: 128px;
    63. }
    64. .ant-upload-select-picture-card i {
    65. font-size: 32px;
    66. color: #999;
    67. }
    68. .ant-upload-select-picture-card .ant-upload-text {
    69. margin-top: 8px;
    70. color: #666;
    71. }
    72. </style>

    Upload上传 - 图3

    已上传的文件列表

    使用 defaultFileList 设置已上传的内容。

    1. <template>
    2. <a-upload action="//jsonplaceholder.typicode.com/posts/" :defaultFileList="defaultFileList">
    3. <a-button>
    4. <a-icon type="upload" /> Upload
    5. </a-button>
    6. </a-upload>
    7. </template>
    8. <script>
    9. export default {
    10. data () {
    11. return {
    12. defaultFileList: [{
    13. uid: '1',
    14. name: 'xxx.png',
    15. status: 'done',
    16. response: 'Server Error 500', // custom error message to show
    17. url: 'http://www.baidu.com/xxx.png',
    18. }, {
    19. uid: '2',
    20. name: 'yyy.png',
    21. status: 'done',
    22. url: 'http://www.baidu.com/yyy.png',
    23. }, {
    24. uid: '3',
    25. name: 'zzz.png',
    26. status: 'error',
    27. response: 'Server Error 500', // custom error message to show
    28. url: 'http://www.baidu.com/zzz.png',
    29. }],
    30. }
    31. },
    32. methods: {
    33. handleChange({file, fileList}) {
    34. if (file.status !== 'uploading') {
    35. console.log(file, fileList);
    36. }
    37. },
    38. },
    39. }
    40. </script>

    Upload上传 - 图4

    照片墙

    用户可以上传图片并在列表中显示缩略图。当上传照片数到达限制后,上传按钮消失。

    1. <template>
    2. <div class="clearfix">
    3. <a-upload
    4. action="//jsonplaceholder.typicode.com/posts/"
    5. listType="picture-card"
    6. :fileList="fileList"
    7. @preview="handlePreview"
    8. @change="handleChange"
    9. >
    10. <div v-if="fileList.length < 3">
    11. <a-icon type="plus" />
    12. <div class="ant-upload-text">Upload</div>
    13. </div>
    14. </a-upload>
    15. <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
    16. <img alt="example" style="width: 100%" :src="previewImage" />
    17. </a-modal>
    18. </div>
    19. </template>
    20. <script>
    21. export default {
    22. data () {
    23. return {
    24. previewVisible: false,
    25. previewImage: '',
    26. fileList: [{
    27. uid: '-1',
    28. name: 'xxx.png',
    29. status: 'done',
    30. url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
    31. }],
    32. }
    33. },
    34. methods: {
    35. handleCancel () {
    36. this.previewVisible = false
    37. },
    38. handlePreview (file) {
    39. this.previewImage = file.url || file.thumbUrl
    40. this.previewVisible = true
    41. },
    42. handleChange ({ fileList }) {
    43. this.fileList = fileList
    44. },
    45. },
    46. }
    47. </script>
    48. <style>
    49. /* you can make up upload button and sample style by using stylesheets */
    50. .ant-upload-select-picture-card i {
    51. font-size: 32px;
    52. color: #999;
    53. }
    54. .ant-upload-select-picture-card .ant-upload-text {
    55. margin-top: 8px;
    56. color: #666;
    57. }
    58. </style>

    Upload上传 - 图5

    完全控制的上传列表

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

    • 上传列表数量的限制。
    • 读取远程路径并显示链接。
    • 按照服务器返回信息筛选成功上传的文件。
    1. <template>
    2. <a-upload action="//jsonplaceholder.typicode.com/posts/" :multiple="true" :fileList="fileList" @change="handleChange">
    3. <a-button>
    4. <a-icon type="upload" /> Upload
    5. </a-button>
    6. </a-upload>
    7. </template>
    8. <script>
    9. export default {
    10. data () {
    11. return {
    12. fileList: [{
    13. uid: '-1',
    14. name: 'xxx.png',
    15. status: 'done',
    16. url: 'http://www.baidu.com/xxx.png',
    17. }],
    18. }
    19. },
    20. methods: {
    21. handleChange(info) {
    22. let fileList = info.fileList;
    23. // 1. Limit the number of uploaded files
    24. // Only to show two recent uploaded files, and old ones will be replaced by the new
    25. fileList = fileList.slice(-2);
    26. // 2. read from response and show file link
    27. fileList = fileList.map((file) => {
    28. if (file.response) {
    29. // Component will show file.url as link
    30. file.url = file.response.url;
    31. }
    32. return file;
    33. });
    34. // 3. filter successfully uploaded files according to response from server
    35. fileList = fileList.filter((file) => {
    36. if (file.response) {
    37. return file.response.status === 'success';
    38. }
    39. return false;
    40. });
    41. this.fileList = fileList
    42. },
    43. },
    44. }
    45. </script>

    Upload上传 - 图6

    拖拽上传

    把文件拖入指定区域,完成上传,同样支持点击上传。设置 multiple 后,在 IE10+ 可以一次上传多个文件。

    1. <template>
    2. <a-upload-dragger name="file" :multiple="true" action="//jsonplaceholder.typicode.com/posts/" @change="handleChange">
    3. <p class="ant-upload-drag-icon">
    4. <a-icon type="inbox" />
    5. </p>
    6. <p class="ant-upload-text">Click or drag file to this area to upload</p>
    7. <p class="ant-upload-hint">Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files</p>
    8. </a-upload-dragger>
    9. </template>
    10. <script>
    11. export default {
    12. data () {
    13. return {}
    14. },
    15. methods: {
    16. handleChange(info) {
    17. const status = info.file.status;
    18. if (status !== 'uploading') {
    19. console.log(info.file, info.fileList);
    20. }
    21. if (status === 'done') {
    22. this.$message.success(`${info.file.name} file uploaded successfully.`);
    23. } else if (status === 'error') {
    24. this.$message.error(`${info.file.name} file upload failed.`);
    25. }
    26. },
    27. },
    28. }
    29. </script>

    Upload上传 - 图7

    图片列表样式

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

    1. <template>
    2. <div>
    3. <a-upload
    4. action="//jsonplaceholder.typicode.com/posts/"
    5. listType="picture"
    6. :defaultFileList="fileList"
    7. >
    8. <a-button>
    9. <a-icon type="upload" /> upload
    10. </a-button>
    11. </a-upload>
    12. <br />
    13. <br />
    14. <a-upload
    15. action="//jsonplaceholder.typicode.com/posts/"
    16. listType="picture"
    17. :defaultFileList="fileList"
    18. class="upload-list-inline"
    19. >
    20. <a-button>
    21. <a-icon type="upload" /> upload
    22. </a-button>
    23. </a-upload>
    24. </div>
    25. </template>
    26. <script>
    27. export default {
    28. data () {
    29. return {
    30. fileList: [{
    31. uid: '-1',
    32. name: 'xxx.png',
    33. status: 'done',
    34. url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
    35. thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
    36. }, {
    37. uid: '-2',
    38. name: 'yyy.png',
    39. status: 'done',
    40. url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
    41. thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
    42. }],
    43. }
    44. },
    45. }
    46. </script>
    47. <style scoped>
    48. /* tile uploaded pictures */
    49. .upload-list-inline >>> .ant-upload-list-item {
    50. float: left;
    51. width: 200px;
    52. margin-right: 8px;
    53. }
    54. .upload-list-inline >>> .ant-upload-animate-enter {
    55. animation-name: uploadAnimateInlineIn;
    56. }
    57. .upload-list-inline >>> .ant-upload-animate-leave {
    58. animation-name: uploadAnimateInlineOut;
    59. }
    60. </style>

    Upload上传 - 图8

    手动上传

    beforeUpload 返回 false 后,手动上传文件。

    1. <template>
    2. <div class="clearfix">
    3. <a-upload
    4. :fileList="fileList"
    5. :remove="handleRemove"
    6. :beforeUpload="beforeUpload"
    7. >
    8. <a-button>
    9. <a-icon type="upload" /> Select File
    10. </a-button>
    11. </a-upload>
    12. <a-button
    13. type="primary"
    14. @click="handleUpload"
    15. :disabled="fileList.length === 0"
    16. :loading="uploading"
    17. style="margin-top: 16px"
    18. >
    19. {{uploading ? 'Uploading' : 'Start Upload' }}
    20. </a-button>
    21. </div>
    22. </template>
    23. <script>
    24. import reqwest from 'reqwest'
    25. export default {
    26. data () {
    27. return {
    28. fileList: [],
    29. uploading: false,
    30. }
    31. },
    32. methods: {
    33. handleRemove(file) {
    34. const index = this.fileList.indexOf(file);
    35. const newFileList = this.fileList.slice();
    36. newFileList.splice(index, 1);
    37. this.fileList = newFileList
    38. },
    39. beforeUpload(file) {
    40. this.fileList = [...this.fileList, file]
    41. return false;
    42. },
    43. handleUpload() {
    44. const { fileList } = this;
    45. const formData = new FormData();
    46. fileList.forEach((file) => {
    47. formData.append('files[]', file);
    48. });
    49. this.uploading = true
    50. // You can use any AJAX library you like
    51. reqwest({
    52. url: '//jsonplaceholder.typicode.com/posts/',
    53. method: 'post',
    54. processData: false,
    55. data: formData,
    56. success: () => {
    57. this.fileList = []
    58. this.uploading = false
    59. this.$message.success('upload successfully.');
    60. },
    61. error: () => {
    62. this.uploading = false
    63. this.$message.error('upload failed.');
    64. },
    65. });
    66. }
    67. },
    68. }
    69. </script>

    Upload上传 - 图9

    文件夹上传

    支持上传一个文件夹里的所有文件。

    1. <template>
    2. <a-upload action="//jsonplaceholder.typicode.com/posts/" directory>
    3. <a-button>
    4. <a-icon type="upload" /> Upload Directory
    5. </a-button>
    6. </a-upload>
    7. </template>

    API

    服务端上传接口实现可以参考 jQuery-File-Upload。

    参数说明类型默认值
    accept接受上传的文件类型, 详见 input accept Attributestring
    action上传的地址string|(file) => Promise
    directory支持上传文件夹(caniuse)booleanfalse
    beforeUpload上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传。支持返回一个 Promise 对象,Promise 对象 reject 时则停止上传,resolve 时开始上传( resolve 传入 FileBlob 对象则上传 resolve 传入对象)。注意:IE9 不支持该方法(file, fileList) => boolean | Promise
    customRequest通过覆盖默认的上传行为,可以自定义自己的上传实现Function
    data上传所需参数或返回上传参数的方法object|(file) => object
    defaultFileList默认已经上传的文件列表object[]
    disabled是否禁用booleanfalse
    fileList已经上传的文件列表(受控)object[]
    headers设置上传的请求头部,IE10 以上有效object
    listType上传列表的内建样式,支持三种基本样式 text, picturepicture-cardstring'text'
    multiple是否支持多选文件,ie10+ 支持。开启后按住 ctrl 可选择多个文件。booleanfalse
    name发到后台的文件参数名string'file'
    showUploadList是否展示 uploadList, 可设为一个对象,用于单独设定 showPreviewIcon 和 showRemoveIconBoolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean }true
    supportServerRender服务端渲染时需要打开这个booleanfalse
    withCredentials上传请求时是否携带 cookiebooleanfalse
    openFileDialogOnClick点击打开文件对话框booleantrue
    remove点击移除文件时的回调,返回值为 false 时不移除。支持返回一个 Promise 对象,Promise 对象 resolve(false) 或 reject 时不移除。Function(file): boolean | Promise

    事件

    事件名称说明回调参数
    change上传文件改变时的状态,详见 changeFunction
    preview点击文件链接或预览图标时的回调Function(file)

    change

    上传中、完成、失败都会调用这个函数。

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

    1. {
    2. file: { /* ... */ },
    3. fileList: [ /* ... */ ],
    4. event: { /* ... */ },
    5. }
    • file 当前操作的文件对象。
    1. {
    2. uid: 'uid', // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突
    3. name: 'xx.png' // 文件名
    4. status: 'done', // 状态有:uploading done error removed
    5. response: '{"status": "success"}', // 服务端响应内容
    6. linkProps: '{"download": "image"}', // 下载链接额外的 HTML 属性
    7. }
    • fileList 当前的文件列表。

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