Uploader 上传

示例

文件上传

设置 type 的值为 file 进入文件上传模式。

Normal size

  • demo-file1.txt
  • demo-file2.txt

Small size

  • demo-file1.txt
  • demo-file2.txt
在 GitHub 上编辑此页编辑
<template>
<article>
  <section>
    <h4>Normal size</h4>
    <veui-uploader
      v-model="files"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
    />
  </section>
  <section>
    <h4>Small size</h4>
    <veui-uploader
      v-model="files2"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
      ui="s"
    />
  </section>
</article>
</template>

<script>
import { Uploader } from 'veui'
import { cloneDeep } from 'lodash'

export default {
  components: {
    'veui-uploader': Uploader
  },
  data () {
    let files = [
      {
        name: 'demo-file1.txt',
        src: '/file/demo-file1.txt',
        key: 0
      },
      {
        name: 'demo-file2.txt',
        src: '/file/demo-file2.txt',
        key: 1
      }
    ]
    return {
      files,
      files2: cloneDeep(files)
    }
  }
}
</script>

<style lang="less" scoped>
article {
  display: flex;
}

section {
  width: 45%;
}
</style>

图片上传

设置 type 的值为 image 进入图片上传模式。

Normal size

Normal size

Small size

Small size
在 GitHub 上编辑此页编辑
<template>
<article>
  <section>
    <h4>Normal size</h4>
    <veui-uploader
      v-model="images"
      type="image"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
    >
      <template #desc>
        Normal size
      </template>
    </veui-uploader>
  </section>
  <section>
    <h4>Small size</h4>
    <veui-uploader
      v-model="images2"
      type="image"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
      ui="s"
    >
      <template #desc>
        Small size
      </template>
    </veui-uploader>
  </section>
</article>
</template>

<script>
import { Uploader } from 'veui'
import { cloneDeep } from 'lodash'

export default {
  components: {
    'veui-uploader': Uploader
  },
  data () {
    let images = [
      {
        src: '/images/development/uploader/demo-image1.jpg',
        key: 0
      },
      {
        src: '/images/development/uploader/demo-image2.jpg',
        key: 1
      }
    ]
    return {
      images,
      images2: cloneDeep(images)
    }
  }
}
</script>

媒体上传

设置 type 的值为 media 进入媒体上传模式。

Normal size

Normal size

Small size

Small size
在 GitHub 上编辑此页编辑
<template>
<article>
  <section>
    <h4>Normal size</h4>
    <veui-uploader
      v-model="media"
      type="media"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
    >
      <template #desc>
        Normal size
      </template>
    </veui-uploader>
  </section>
  <section>
    <h4>Small size</h4>
    <veui-uploader
      v-model="media2"
      type="media"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
      ui="s"
    >
      <template #desc>
        Small size
      </template>
    </veui-uploader>
  </section>
</article>
</template>

<script>
import { Uploader } from 'veui'
import { cloneDeep } from 'lodash'

export default {
  components: {
    'veui-uploader': Uploader
  },
  data () {
    let media = [
      {
        type: 'image',
        src: '/images/development/uploader/demo-image1.jpg',
        key: 0
      },
      {
        type: 'video',
        src: 'https://nadvideo2.baidu.com/5dafd8544f4f53b27a5f59b0ab780403_1920_1080.mp4',
        poster: 'https://feed-image.baidu.com/0/pic/4dced79d185a16e228652b136f653dcc.jpg',
        key: 1
      }
    ]
    return {
      media,
      media2: cloneDeep(media)
    }
  }
}
</script>

前端校验

图片格式、大小、数量校验以及使用 validator 自定义校验。

请选择jpg、png图片,大小不超过100kb,宽高分别大于200px,最多上传6张图片
在 GitHub 上编辑此页编辑
<template>
<article>
  <section>
    <veui-uploader
      v-model="images"
      type="image"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
      accept="jpg,png"
      :max-count="6"
      max-size="100kb"
      :validator="validator"
    >
      <template #desc>
        请选择jpg、png图片,大小不超过100kb,宽高分别大于200px,最多上传6张图片
      </template>
    </veui-uploader>
  </section>
</article>
</template>

<script>
import { Uploader } from 'veui'

export default {
  components: {
    'veui-uploader': Uploader
  },
  data () {
    return {
      images: [
        {
          src: '/images/development/uploader/demo-image1.jpg',
          key: 0
        },
        {
          src: '/images/development/uploader/demo-image2.jpg',
          key: 1
        }
      ],
      validator (file) {
        return new Promise(resolve => {
          let image = new Image()
          image.src = window.URL.createObjectURL(file)
          image.onload = () => {
            resolve({
              valid: image.height > 200 && image.width > 200,
              message: '图片宽高太小'
            })
          }
        })
      }
    }
  }
}
</script>

自定义配置

使用 upload 自定义上传过程,使用 controls 配置浮层操作项。

点击图片浮层上的向右箭头按钮改变图片位置
在 GitHub 上编辑此页编辑
<template>
<article>
  <section>
    <veui-uploader
      v-model="images"
      type="image"
      :action="action"
      :controls="controls"
      request-mode="custom"
      :upload="upload"
      @moveright="handleMoveRight"
    >
      <template #desc>
        点击图片浮层上的向右箭头按钮改变图片位置
      </template>
    </veui-uploader>
  </section>
</article>
</template>

<script>
import { Uploader } from 'veui'

export default {
  components: {
    'veui-uploader': Uploader
  },
  data () {
    return {
      action: 'https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog',
      images: [
        {
          key: 0,
          src: '/images/development/uploader/demo-image1.jpg'
        },
        {
          key: 1,
          src: '/images/development/uploader/demo-image2.jpg'
        }
      ],
      controls (file, defaultControls) {
        if (file.status === 'success') {
          return [
            { name: 'moveright', icon: 'chevron-right', disabled: false },
            ...defaultControls
          ]
        }
        return defaultControls
      },
      upload: (file, { onload, onprogress, onerror }) => {
        let xhr = new XMLHttpRequest()
        file.xhr = xhr

        xhr.upload.onprogress = e => onprogress(e)
        xhr.onload = e => {
          try {
            onload(JSON.parse(xhr.responseText))
          } catch (e) {
            onload({ success: false, message: e })
          }
        }
        xhr.onerror = e => onerror(e)
        let formData = new FormData()
        formData.append('file', file)

        xhr.open('POST', this.action, true)
        xhr.send(formData)

        return () => {
          xhr.abort()
        }
      }
    }
  },
  methods: {
    handleMoveRight (file, index) {
      if (index < this.images.length - 1) {
        let temp = { ...this.images[index] }
        this.$set(this.images, index, this.images[index + 1])
        this.$set(this.images, index + 1, temp)
      }
    }
  }
}
</script>

拖拽排序

设置 sortable 属性来指定上传项目之间可以拖拽排序。

在 GitHub 上编辑此页编辑
<template>
<article>
  <section>
    <veui-uploader
      v-model="images"
      sortable
      type="image"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
    />
  </section>
</article>
</template>

<script>
import { Uploader } from 'veui'

export default {
  components: {
    'veui-uploader': Uploader
  },
  data () {
    return {
      images: [
        {
          key: 0,
          src: '/images/development/uploader/demo-image1.jpg'
        },
        {
          key: 1,
          src: '/images/development/uploader/demo-image2.jpg'
        }
      ]
    }
  }
}
</script>

已上传项自定义操作

设置 controls 属性来指定悬浮到每个上传项时的操作选项。

controls 自定义的操作,点击会触发同名事件,事件参数为该上传项数据和 status 字段, 即通常是 {src, key, type, status, ...}

在 GitHub 上编辑此页编辑
<template>
<article>
  <section>
    <veui-uploader
      v-model="images"
      :controls="controls"
      type="image"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
      @star="handleStar"
    />
  </section>
</article>
</template>

<script>
import { Uploader, toast } from 'veui'
import 'veui-theme-dls-icons/star'

export default {
  components: {
    'veui-uploader': Uploader
  },
  data () {
    return {
      images: [
        {
          key: 0,
          src: '/images/development/uploader/demo-image1.jpg'
        },
        {
          key: 1,
          src: '/images/development/uploader/demo-image2.jpg'
        }
      ],
      controls (item, defaultControls) {
        return [
          ...defaultControls,
          {
            name: 'star',
            icon: 'star',
            label: 'star'
          }
        ]
      }
    }
  },
  methods: {
    handleStar () {
      toast.info('You click star!')
    }
  }
}
</script>

上传入口自定义操作

设置 entries 属性来指定悬浮到继续上传项目时的操作选项。

entries 自定义的操作,点击会触发同名事件,事件参数为空。

在 GitHub 上编辑此页编辑
<template>
<article>
  <section>
    <veui-uploader
      v-model="images"
      :entries="entries"
      type="image"
      action="https://app.fakejson.com/q/ELymQ7xh?token=AWFkjMICPSAB_bO_z-Lnog"
      @star="handleStar"
    />
  </section>
</article>
</template>

<script>
import { Uploader, toast } from 'veui'
import 'veui-theme-dls-icons/star'

export default {
  components: {
    'veui-uploader': Uploader
  },
  data () {
    return {
      images: [
        {
          key: 0,
          src: '/images/development/uploader/demo-image1.jpg'
        },
        {
          key: 1,
          src: '/images/development/uploader/demo-image2.jpg'
        }
      ],
      entries (defaultEntries) {
        return [
          ...defaultEntries,
          {
            name: 'star',
            icon: 'star',
            label: 'star'
          }
        ]
      }
    }
  },
  methods: {
    handleStar () {
      toast.info('You clicked star!')
    }
  }
}
</script>

API

属性

属性类型默认值描述
uistring=-

预设样式。

描述
s小尺寸样式。
m中尺寸样式。
typestring'file'

上传类型。

描述
file文件上传。
image图片上传。
media媒体上传(支持视频和图片)。
video视频上传。
valueObject | Array<Object>-

multipletrue,返回文件对象的数组。另外,当 max-count 被设置为大于 1 的值,则会视为开启了 multiple

每个文件对象的类型为 {name: string, src: string, ...},以及在 convert-response 中自定义添加的字段。

key-fieldstring'key'用于指定文件对象的唯一 key,作为数据变化时正确处理文件列表顺序的依据。
namestring'file'原生 <input> 元素的 name
actionstring-上传地址。
headersObjectuploader.headers需要加入 HTTP 请求头 的内容。可进行全局统一配置
with-credentialsbooleantrueXMLHttpRequestwithCredentials 属性。
request-modestringuploader.requestMode

指定异步上传方式。可进行全局统一配置

描述
xhr通过 XMLHttpRequest 上传。
iframe通过 <iframe> 上传。
custom自定义上传过程,通过 prop upload 方法上传。
iframe-modestringuploader.iframeMode

指定在 request-mode 的值为 iframe 的模式下,上传成功后的回调方式。可进行全局统一配置

描述
postmessage通过 PostMessage 回调。
callback通过调用 windowcallback-namespace 里的回调函数回调。
callback-namespacestringuploader.callbackNamespacerequest-mode 的值为 'iframe' 并且 iframe-mode 的值为 'callback' 的模式下,指定回调函数的命名空间,放在 window 对象下。可进行全局统一配置
data-typestring'json'

如果回调的值是文本, 指明文本的解析方式。如果回调的数据是 Object,则 data-type 可以为空。

描述
json回调的文本是 JSON。
text回调的文本是普通文本。
convert-responseuploader.convertResponse-

将回调数据转换成需要的格式的函数,使组件能够判断上传是否成功以便显示相应结果,参数是回调数据。返回结果的格式要求如下:

字段类型描述
successboolean表示上传是否成功。
namestring=文件的名称。successtrue 时必须。
srcstring=文件的地址。successtrue 时必须。
messagestring=上传失败时的出错信息。successfalse 时必须。

还可以给返回结果加上其它自定义的属性,这些自定义属性会被包含在 value 以及 changesuccessfailureremoveprogress 事件的回调参数 file 中 。可进行全局统一配置

acceptstring-与原生 <input> 元素 的 accept 属性相同,在浏览器的文件类型筛选后再加一层校验。对于类似 application/msword 这样的 MIME type 与扩展名对不上的情形跳过校验。
max-countnumber-最大文件数量。
max-sizenumber | string-单个文件的最大大小,如果是 number,单位是 byte;如果是 string,支持在数字后面添加单位,单位可以是 b / kb / mb / gb / tb
validatorfunction(Object): Object | Promise<Object>-

自定义校验逻辑,参数为原生 File 对象。返回结果的格式要求如下:

字段类型描述
validboolean是否通过校验。
messagestring=validfalse 时的错误提示信息。

支持异步校验,返回值可以是一个 resolve 上述返回结果的 Promise

payloadObject-附带在上传请求中的额外参数。
autouploadbooleantrue指定是否在选完文件后立刻上传。
orderstring'asc'

上传文件的显示顺序,按照开始上传的时间排序。

描述
asc升序排列。
desc降序排列。
picker-positionstring'after'

图片上传模式下,上传按钮在图片队列中的位置。

描述
before上传按钮始终在队列最前面。
after上传按钮始终在队列最后面。
uploadfunction(Object, Object): function-

request-mode 的值是 'custom' 的情况下自定义上传过程,第一个参数为原生 File 对象,第二个参数为包含与上传过程相关的回调函数的对象,具体字段如下:

字段类型描述
onloadfunction上传完成的回调函数,参数内容与 convert-response 属性返回值相同。
onprogressfunction上传进度发生变化的回调函数,参数为 { loaded: number, total: number }loaded 为已上传部分字节数,total 为文件总字节数。
oncancelfunction自定义上传主动取消时对组件进行的回调,无参数。
onerrorfunction上传出错的回调函数,参数为 { message: string }message 为错误提示信息。

如果 upload 返回一个函数,该函数将在用户操作取消或上传组件销毁时被调用,用来中断自定义上传过程。

controlsfunction(Object, Array<Object>): Array<Object>-

图片上传模式下,用来自定义配置图片遮罩浮层上的操作项,参数为 (file: Object, defaultControls: Array<Object>)file 为文件相关信息,defaultControls 为包含默认的操作项的数组。可根据文件状态的不同,返回包含不同的操作项的数组。每个操作项的具体字段如下:

字段类型描述
namestring操作项的名称,点击该按钮后会抛出同名的事件,事件的回调参数为 (file: Object, index: number)file 为触发事件的文件对象,index 为文件在列表中的序号。
labelstring操作项的文字描述。
iconstring操作项使用的图标。
disabledboolean=操作项是否被禁用。如果该字段为空,则该操作项的禁用状态跟随组件整体的禁用状态。
multiplebooleanfalse上传多个文件,当 max-count1multipletrue,那么 value 也是数组。
entriesfunction(Array<Object>): Array<Object>-

控制每个上传文件的操作项,如删除,预览等,会传递默认的操作项数组作为参数,返回实际生效的操作项数组。操作项对象参考 controls 属性的字段详情。

after-pickfunction(Array<Object>): void-选择文件之后的回调。
sortablebooleanfalse文件列表是否可以排序。
preview-optionsobject{wrap: true, indicator: 'number'}传递给 Lightbox 的预览选项。

插槽

名称描述
button-label

上传按钮里的内容。

默认内容:文件上传为提示选择文件,图片上传则为上传图片图标。

upload图片上传模式下,上传按钮的区域。
desc对文件数量、格式、大小等的提示内容。
file

单个文件的区域,用来定制文件内容。

名称类型描述
namestring文件的名称。
srcstring文件的地址。
statusstring文件的状态。'success' 表示上传成功;'uploading' 表示正在上传;'failure' 表示上传失败。
indexnumber文件在列表中的序号。
file-before单个文件内容之前的区域。作用域参数与 file 插槽相同。
file-after单个文件内容之后的区域。作用域参数与 file 插槽相同。
uploading图片上传模式下,上传中的单个图片的区域。作用域参数与 file 插槽相同。
failure图片上传模式下,上传失败的单个图片的区域。作用域参数与 file 插槽相同。

事件

名称描述
change

只在上传成功、删除文件时触发,回调参数为 (value)

名称类型描述
valueObject | Array<Object>组件的 value 的值。
remove

删除文件时触发,回调参数为 (file, index)

名称类型描述
fileObject被删除的文件。
indexnumber被删除的文件的序号。

file 字段详情

字段类型描述
namestring文件名称。
srcstring文件地址。
statusstring上传状态。'success' 表示上传成功;'uploading' 表示正在上传;'failure' 表示上传失败。

同时也包含在 convert-response 中添加的自定义属性。

success上传成功时触发,回调参数与 remove 事件的回调参数相同。
failure上传失败时触发,回调参数与 remove 事件的回调参数相同。
invalid

文件校验失败时触发,回调参数为 (validity: Object)

名称类型描述
fileObject没有通过校验的文件信息,与 remove 事件的回调参数中的 file 相同。如果校验失败的原因是选择的文件数量超过最大数量 max-count 限制,则这个字段为空。
errorsArray<Object>包含该文件所有校验错误信息的数组,数组的每一项是包含校验失败信息的对象。
名称类型描述
typestring校验失败的类型,类型枚举值可从 Uploader.errors 对象获取,如 Uploader.errors.SIZE_INVALID
valuenumber | string | Object没有通过校验的值,根据 type 的不同有不同的类型。
messagestring检验失败的提示信息。
类型描述value 类型value 描述
TYPE_INVALID文件类型校验失败。string文件名称。
SIZE_INVALID文件大小校验失败。number文件大小字节数。
TOO_MANY_FILES选择的文件数超过 max-count 限制。number已选择的文件数。
CUSTOM_INVALIDvalidator 自定义校验失败。Object文件对象,字段同 remove 事件回调参数。
statuschange

在所有文件总的状态发生变化时触发,回调参数为组件整体的状态 (status: string)

描述
empty没有选择任何文件上传。
uploading有任一文件正在上传中。
failure有任一文件上传失败。
success所有文件上传成功。
progress

request-mode 的值为 'xhr' 的情况下,在上传进度发生变化时触发,回调参数为 (file, index, event)

名称类型描述
fileObjectremove 事件的回调参数中的 file 相同。
indexnumber正在上传的文件的序号。
eventEvent上传进度原生事件。

全局配置

名称类型默认值描述
uploader.requestModestring'xhr'参见 request-mode 属性。
uploader.iframeModestring'postmessage'参见 iframe-mode 属性。
uploader.callbackNamespacestring'veuiUploadResult'参见 callback-namespace 属性。
uploader.headersObject-参见 headers 属性。
uploader.convertResponsefunction(Object): Object-参见 convert-response 属性。
uploader.pickerPositionstring'after'参见 picker-position 属性。

图标

名称描述
upload上传文件。
add-image上传图片。
clear删除。
success上传成功。
failure上传失败。
loading上传中。
file已上传文件。
alert校验失败警告。
preview预览图片。
在 GitHub 上编辑此页编辑