Upload 上传

通过点击或者拖拽上传文件

基础用法

通过 slot 你可以传入自定义的上传按钮类型和文字提示。 可通过设置 limiton-exceed 来限制上传文件的个数和定义超出限制时的行为。 可通过设置 before-remove 来阻止文件移除操作。

Upload 上传 - 图1

  1. <template>
  2. <el-upload
  3. v-model:file-list="fileList"
  4. class="upload-demo"
  5. action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
  6. multiple
  7. :on-preview="handlePreview"
  8. :on-remove="handleRemove"
  9. :before-remove="beforeRemove"
  10. :limit="3"
  11. :on-exceed="handleExceed"
  12. >
  13. <el-button type="primary">Click to upload</el-button>
  14. <template #tip>
  15. <div class="el-upload__tip">
  16. jpg/png files with a size less than 500KB.
  17. </div>
  18. </template>
  19. </el-upload>
  20. </template>
  21. <script lang="ts" setup>
  22. import { ref } from 'vue'
  23. import { ElMessage, ElMessageBox } from 'element-plus'
  24. import type { UploadProps, UploadUserFile } from 'element-plus'
  25. const fileList = ref<UploadUserFile[]>([
  26. {
  27. name: 'element-plus-logo.svg',
  28. url: 'https://element-plus.org/images/element-plus-logo.svg',
  29. },
  30. {
  31. name: 'element-plus-logo2.svg',
  32. url: 'https://element-plus.org/images/element-plus-logo.svg',
  33. },
  34. ])
  35. const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
  36. console.log(file, uploadFiles)
  37. }
  38. const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
  39. console.log(uploadFile)
  40. }
  41. const handleExceed: UploadProps['onExceed'] = (files, uploadFiles) => {
  42. ElMessage.warning(
  43. `The limit is 3, you selected ${files.length} files this time, add up to ${
  44. files.length + uploadFiles.length
  45. } totally`
  46. )
  47. }
  48. const beforeRemove: UploadProps['beforeRemove'] = (uploadFile, uploadFiles) => {
  49. return ElMessageBox.confirm(
  50. `Cancel the transfert of ${uploadFile.name} ?`
  51. ).then(
  52. () => true,
  53. () => false
  54. )
  55. }
  56. </script>

覆盖前一个文件

设置 limiton-exceed 可以在选中时自动替换上一个文件。

Upload 上传 - 图2

  1. <template>
  2. <el-upload
  3. ref="upload"
  4. class="upload-demo"
  5. action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
  6. :limit="1"
  7. :on-exceed="handleExceed"
  8. :auto-upload="false"
  9. >
  10. <template #trigger>
  11. <el-button type="primary">select file</el-button>
  12. </template>
  13. <el-button class="ml-3" type="success" @click="submitUpload">
  14. upload to server
  15. </el-button>
  16. <template #tip>
  17. <div class="el-upload__tip text-red">
  18. limit 1 file, new file will cover the old file
  19. </div>
  20. </template>
  21. </el-upload>
  22. </template>
  23. <script setup lang="ts">
  24. import { ref } from 'vue'
  25. import { genFileId } from 'element-plus'
  26. import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
  27. const upload = ref<UploadInstance>()
  28. const handleExceed: UploadProps['onExceed'] = (files) => {
  29. upload.value!.clearFiles()
  30. const file = files[0] as UploadRawFile
  31. file.uid = genFileId()
  32. upload.value!.handleStart(file)
  33. }
  34. const submitUpload = () => {
  35. upload.value!.submit()
  36. }
  37. </script>

用户头像

before-upload 钩子中限制用户上传文件的格式和大小。

Upload 上传 - 图3

  1. <template>
  2. <el-upload
  3. class="avatar-uploader"
  4. action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
  5. :show-file-list="false"
  6. :on-success="handleAvatarSuccess"
  7. :before-upload="beforeAvatarUpload"
  8. >
  9. <img v-if="imageUrl" :src="imageUrl" class="avatar" />
  10. <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
  11. </el-upload>
  12. </template>
  13. <script lang="ts" setup>
  14. import { ref } from 'vue'
  15. import { ElMessage } from 'element-plus'
  16. import { Plus } from '@element-plus/icons-vue'
  17. import type { UploadProps } from 'element-plus'
  18. const imageUrl = ref('')
  19. const handleAvatarSuccess: UploadProps['onSuccess'] = (
  20. response,
  21. uploadFile
  22. ) => {
  23. imageUrl.value = URL.createObjectURL(uploadFile.raw!)
  24. }
  25. const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
  26. if (rawFile.type !== 'image/jpeg') {
  27. ElMessage.error('Avatar picture must be JPG format!')
  28. return false
  29. } else if (rawFile.size / 1024 / 1024 > 2) {
  30. ElMessage.error('Avatar picture size can not exceed 2MB!')
  31. return false
  32. }
  33. return true
  34. }
  35. </script>
  36. <style scoped>
  37. .avatar-uploader .avatar {
  38. width: 178px;
  39. height: 178px;
  40. display: block;
  41. }
  42. </style>
  43. <style>
  44. .avatar-uploader .el-upload {
  45. border: 1px dashed var(--el-border-color);
  46. border-radius: 6px;
  47. cursor: pointer;
  48. position: relative;
  49. overflow: hidden;
  50. transition: var(--el-transition-duration-fast);
  51. }
  52. .avatar-uploader .el-upload:hover {
  53. border-color: var(--el-color-primary);
  54. }
  55. .el-icon.avatar-uploader-icon {
  56. font-size: 28px;
  57. color: #8c939d;
  58. width: 178px;
  59. height: 178px;
  60. text-align: center;
  61. }
  62. </style>

照片墙

使用 list-type 属性来设定文件列表的样式。

Upload 上传 - 图4

  1. <template>
  2. <el-upload
  3. v-model:file-list="fileList"
  4. action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
  5. list-type="picture-card"
  6. :on-preview="handlePictureCardPreview"
  7. :on-remove="handleRemove"
  8. >
  9. <el-icon><Plus /></el-icon>
  10. </el-upload>
  11. <el-dialog v-model="dialogVisible">
  12. <img w-full :src="dialogImageUrl" alt="Preview Image" />
  13. </el-dialog>
  14. </template>
  15. <script lang="ts" setup>
  16. import { ref } from 'vue'
  17. import { Plus } from '@element-plus/icons-vue'
  18. import type { UploadProps, UploadUserFile } from 'element-plus'
  19. const fileList = ref<UploadUserFile[]>([
  20. {
  21. name: 'food.jpeg',
  22. url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
  23. },
  24. {
  25. name: 'plant-1.png',
  26. url: '/images/plant-1.png',
  27. },
  28. {
  29. name: 'food.jpeg',
  30. url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
  31. },
  32. {
  33. name: 'plant-2.png',
  34. url: '/images/plant-2.png',
  35. },
  36. {
  37. name: 'food.jpeg',
  38. url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
  39. },
  40. {
  41. name: 'figure-1.png',
  42. url: '/images/figure-1.png',
  43. },
  44. {
  45. name: 'food.jpeg',
  46. url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
  47. },
  48. {
  49. name: 'figure-2.png',
  50. url: '/images/figure-2.png',
  51. },
  52. ])
  53. const dialogImageUrl = ref('')
  54. const dialogVisible = ref(false)
  55. const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  56. console.log(uploadFile, uploadFiles)
  57. }
  58. const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  59. dialogImageUrl.value = uploadFile.url!
  60. dialogVisible.value = true
  61. }
  62. </script>

自定义缩略图

使用 scoped-slot 属性来改变默认的缩略图模板样式。

Upload 上传 - 图5

  1. <template>
  2. <el-upload action="#" list-type="picture-card" :auto-upload="false">
  3. <el-icon><Plus /></el-icon>
  4. <template #file="{ file }">
  5. <div>
  6. <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
  7. <span class="el-upload-list__item-actions">
  8. <span
  9. class="el-upload-list__item-preview"
  10. @click="handlePictureCardPreview(file)"
  11. >
  12. <el-icon><zoom-in /></el-icon>
  13. </span>
  14. <span
  15. v-if="!disabled"
  16. class="el-upload-list__item-delete"
  17. @click="handleDownload(file)"
  18. >
  19. <el-icon><Download /></el-icon>
  20. </span>
  21. <span
  22. v-if="!disabled"
  23. class="el-upload-list__item-delete"
  24. @click="handleRemove(file)"
  25. >
  26. <el-icon><Delete /></el-icon>
  27. </span>
  28. </span>
  29. </div>
  30. </template>
  31. </el-upload>
  32. <el-dialog v-model="dialogVisible">
  33. <img w-full :src="dialogImageUrl" alt="Preview Image" />
  34. </el-dialog>
  35. </template>
  36. <script lang="ts" setup>
  37. import { ref } from 'vue'
  38. import { Delete, Download, Plus, ZoomIn } from '@element-plus/icons-vue'
  39. import type { UploadFile } from 'element-plus'
  40. const dialogImageUrl = ref('')
  41. const dialogVisible = ref(false)
  42. const disabled = ref(false)
  43. const handleRemove = (file: UploadFile) => {
  44. console.log(file)
  45. }
  46. const handlePictureCardPreview = (file: UploadFile) => {
  47. dialogImageUrl.value = file.url!
  48. dialogVisible.value = true
  49. }
  50. const handleDownload = (file: UploadFile) => {
  51. console.log(file)
  52. }
  53. </script>

图片列表缩略图

Upload 上传 - 图6

  1. <template>
  2. <el-upload
  3. v-model:file-list="fileList"
  4. class="upload-demo"
  5. action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
  6. :on-preview="handlePreview"
  7. :on-remove="handleRemove"
  8. list-type="picture"
  9. >
  10. <el-button type="primary">Click to upload</el-button>
  11. <template #tip>
  12. <div class="el-upload__tip">
  13. jpg/png files with a size less than 500kb
  14. </div>
  15. </template>
  16. </el-upload>
  17. </template>
  18. <script lang="ts" setup>
  19. import { ref } from 'vue'
  20. import type { UploadProps, UploadUserFile } from 'element-plus'
  21. const fileList = ref<UploadUserFile[]>([
  22. {
  23. name: 'food.jpeg',
  24. url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
  25. },
  26. {
  27. name: 'food2.jpeg',
  28. url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
  29. },
  30. ])
  31. const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  32. console.log(uploadFile, uploadFiles)
  33. }
  34. const handlePreview: UploadProps['onPreview'] = (file) => {
  35. console.log(file)
  36. }
  37. </script>

上传文件列表控制

通过 on-change 钩子函数来对列表进行控制

Upload 上传 - 图7

  1. <template>
  2. <el-upload
  3. v-model:file-list="fileList"
  4. class="upload-demo"
  5. action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
  6. :on-change="handleChange"
  7. >
  8. <el-button type="primary">Click to upload</el-button>
  9. <template #tip>
  10. <div class="el-upload__tip">
  11. jpg/png files with a size less than 500kb
  12. </div>
  13. </template>
  14. </el-upload>
  15. </template>
  16. <script lang="ts" setup>
  17. import { ref } from 'vue'
  18. import type { UploadProps, UploadUserFile } from 'element-plus'
  19. const fileList = ref<UploadUserFile[]>([
  20. {
  21. name: 'food.jpeg',
  22. url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
  23. },
  24. {
  25. name: 'food2.jpeg',
  26. url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
  27. },
  28. ])
  29. const handleChange: UploadProps['onChange'] = (uploadFile, uploadFiles) => {
  30. fileList.value = fileList.value.slice(-3)
  31. }
  32. </script>

拖拽上传

你可以将文件拖拽到特定区域以进行上传。

Upload 上传 - 图8

  1. <template>
  2. <el-upload
  3. class="upload-demo"
  4. drag
  5. action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
  6. multiple
  7. >
  8. <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  9. <div class="el-upload__text">
  10. Drop file here or <em>click to upload</em>
  11. </div>
  12. <template #tip>
  13. <div class="el-upload__tip">
  14. jpg/png files with a size less than 500kb
  15. </div>
  16. </template>
  17. </el-upload>
  18. </template>
  19. <script setup lang="ts">
  20. import { UploadFilled } from '@element-plus/icons-vue'
  21. </script>

手动上传

Upload 上传 - 图9

  1. <template>
  2. <el-upload
  3. ref="uploadRef"
  4. class="upload-demo"
  5. action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
  6. :auto-upload="false"
  7. >
  8. <template #trigger>
  9. <el-button type="primary">select file</el-button>
  10. </template>
  11. <el-button class="ml-3" type="success" @click="submitUpload">
  12. upload to server
  13. </el-button>
  14. <template #tip>
  15. <div class="el-upload__tip">
  16. jpg/png files with a size less than 500kb
  17. </div>
  18. </template>
  19. </el-upload>
  20. </template>
  21. <script lang="ts" setup>
  22. import { ref } from 'vue'
  23. import type { UploadInstance } from 'element-plus'
  24. const uploadRef = ref<UploadInstance>()
  25. const submitUpload = () => {
  26. uploadRef.value!.submit()
  27. }
  28. </script>

上传 API

属性

名称描述类型默认值必填
action请求 URLstring
headers设置上传的请求头部Headers | Record<string, any>
method设置上传请求方法string‘post’
multiple是否支持多选文件booleanfalse
data上传时附带的额外参数Record<string, any>
name上传的文件字段名string‘file’
with-credentials支持发送 cookie 凭证信息booleanfalse
show-file-list是否显示已上传文件列表booleantrue
drag是否启用拖拽上传booleanfalse
accept接受上传的 文件类型 Upload 上传 - 图10 (thumbnail-mode 模式下此参数无效)string
on-preview点击文件列表中已上传的文件时的钩子(uploadFile: UploadFile) => void
on-remove文件列表移除文件时的钩子(uploadFile: UploadFile, uploadFiles: UploadFiles) => void
on-success文件上传成功时的钩子(response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => void
on-error文件上传失败时的钩子(error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles) => void
on-progress文件上传时的钩子(evt: UploadProgressEvent, uploadFile: UploadFile, uploadFiles: UploadFiles) => void
on-change文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用(uploadFile: UploadFile, uploadFiles: UploadFiles) => void
on-exceed当超出限制时,执行的钩子函数(files: File[], uploadFiles: UploadFiles) => void
before-upload上传文件之前的钩子,参数为上传的文件, 若返回false或者返回 Promise 且被 reject,则停止上传。(rawFile: UploadRawFile) => Awaitable<void | undefined | null | boolean | File | Blob>
before-remove删除文件之前的钩子,参数为上传的文件和文件列表, 若返回 false 或者返回 Promise 且被 reject,则停止删除。(uploadFile: UploadFile, uploadFiles: UploadFiles) => Awaitable<boolean>
file-list / v-model:file-list默认上传文件UploadUserFile[][]
list-type文件列表的类型“text” | “picture” | “picture-card”‘text’
auto-upload是否自动上传文件booleantrue
http-request覆盖默认的 Xhr 行为,允许自行实现上传文件的请求(options: UploadRequestOptions) => XMLHttpRequest \Promise<unknown>
disabled是否禁用上传booleanfalse
limit允许上传文件的最大数量number

插槽

名称描述Scope
default自定义默认内容-
trigger触发文件选择框的内容-
tip提示说明文字-
file缩略图模板的内容{ file: UploadFile }

外部方法

名称描述类型
abort取消上传请求(file: UploadFile) => void
submit手动上传文件列表() => void
clearFiles清空已上传的文件列表(该方法不支持在 before-upload 中调用)(status?: Array<”ready” | “uploading” | “success” | “fail”>) => void
handleStart手动选择文件(rawFile: UploadRawFile) => void
handleRemove手动移除文件。 filerawFile 已被合并。 rawFile 将在 v2.2.0 中移除(file: UploadFile | UploadRawFile, rawFile?: UploadRawFile) => void

源代码

组件 Upload 上传 - 图11 文档 Upload 上传 - 图12

贡献者

Upload 上传 - 图13 三咲智子

Upload 上传 - 图14 云游君

Upload 上传 - 图15 JeremyWuuuuu

Upload 上传 - 图16 C.Y.Kun

Upload 上传 - 图17 joson

Upload 上传 - 图18 zz

Upload 上传 - 图19 Xc

Upload 上传 - 图20 류한경

Upload 上传 - 图21 Alan Wang

Upload 上传 - 图22 Aex

Upload 上传 - 图23 dopamine

Upload 上传 - 图24 Delyan Haralanov

Upload 上传 - 图25 LYlanfeng

Upload 上传 - 图26 msidolphin

Upload 上传 - 图27 Herb Brewer

Upload 上传 - 图28 bqy

Upload 上传 - 图29 sumy

Upload 上传 - 图30 btea

Upload 上传 - 图31 wxyong

Upload 上传 - 图32 高奕GaoYi

Upload 上传 - 图33 啝裳

Upload 上传 - 图34 iamkun

Upload 上传 - 图35 Soul

Upload 上传 - 图36 on the field of hope

Upload 上传 - 图37 Hades-li

Upload 上传 - 图38 卡西猫倒

Upload 上传 - 图39 Marco Velarde

Upload 上传 - 图40 qiang