UseElUpload - 上传器
组件介绍
UseElUpload 是基于 Element Plus 的 ElUpload 二次封装的文件上传组件,专注于提供开箱即用的文件类型校验、大小限制、数量控制、图片预览、文件下载能力,内置标准化的文件类型配置、删除二次确认、上传中断机制,完整支持 v-model 双向绑定与数据回显,兼容全局上传配置注入,可直接替换原生 ElUpload 使用,大幅降低文件上传场景的重复开发成本。
核心能力
- 标准化的文件类型管理
内置四种预设上传类型(ALL/IMG/VIDEO/EXCLUDE_VIDEO),每种类型预配置支持的文件扩展名与用户提示文案,自动生成 accept 属性限制文件选择,上传前自动校验文件后缀合法性,无需手动维护文件类型白名单,IMG 类型自动切换照片墙展示模式。
- 开箱即用的上传校验能力
内置文件大小校验(默认最大 2GB,可通过 maxSize 自定义)、文件数量限制(默认单文件,limit 配置数量),超出限制时自动弹出友好提示,上传前拦截非法文件,避免无效请求;limit > 1 时自动开启多文件上传,达到数量上限自动隐藏上传按钮。
- 内置图片预览与文件下载
IMG 类型上传的图片点击自动弹出预览弹窗,支持大图查看;非图片类型点击自动触发文件下载,自动从响应数据或回显数据中提取下载链接,无需额外处理预览与下载逻辑,未上传完成的文件自动提示无法预览/下载。
- 安全的删除二次确认机制
删除文件前自动弹出二次确认框,避免误删操作;删除正在上传中的文件时,自动通过 AbortController 中断上传请求,释放网络资源,防止无效请求继续占用带宽。
- 完善的 v-model 双向绑定
原生支持 fileId 与 linkUrl 的双向绑定,多文件上传时自动将文件 ID 与访问链接用逗号拼接,内部使用 300ms 防抖更新,避免频繁触发响应式更新;上传成功、删除文件、数据回显时自动同步绑定值。
- 智能的数据回显能力
通过 uploadList 属性支持已上传文件的数据回显,自动识别文件 ID、原始文件名、访问链接,兼容不同后端返回字段格式;内部标记上传/删除状态,避免用户操作后回显数据覆盖当前文件列表。
- 灵活的全局配置支持
支持通过全局配置注入统一的上传地址(action)、请求头(headers)、额外参数(data),组件级 uploadConfig 可覆盖全局配置,遵循「组件局部配置 > 全局默认配置」优先级规则,无需每个组件重复配置上传接口信息。
- 拖拽上传与样式统一
默认开启拖拽上传交互,优化上传区域尺寸与样式,修复原生上传组件进度条位置异常、文件名展示不全等样式问题,照片墙模式下去除默认边框保持视觉统一,禁用状态下自动隐藏上传按钮。
- 统一的错误处理机制
上传失败时自动解析后端返回错误信息,统一弹出错误提示,通过 onError 事件向外抛出错误详情;上传成功但返回数据格式不符合规范时自动提示,保证错误信息的一致性与可追溯性。
- 安全的生命周期管理
组件卸载时自动中断所有正在进行的上传请求,取消防抖函数执行,避免内存泄漏与无效回调;预览弹窗关闭时自动清空预览图片地址,释放资源,保证组件在动态渲染、频繁切换场景下的稳定性。
使用
Props
import type { PropType } from 'vue'
import type { UploadConfig } from '@/types'
/**
* 组件props
*/
export default {
/**
* 文件id
*/
fileId: {
type: String,
default: ''
},
/**
* 链接地址
*/
linkUrl: {
type: String,
default: ''
},
/**
* 上传配置
* action:请求URL,eg:'/api/file/upload'
* headers:设置上传的请求头部,eg:{ Authorization: `Bearer ${token}` }
* data:上传时附带的额外参数,eg:{ referer: window.location.href }
*/
uploadConfig: {
type: Object as PropType<UploadConfig>,
default: () => ({
// action: '/api/file/upload',
// headers: { Authorization: `Bearer ${token}` },
// data: { referer: window.location.href }
})
},
/**
* 上传类型
* 为ALL支持所有文件格式
* 为IMG仅可上传支持的图片格式且按照片墙形式展示
* 为VIDEO仅可上传支持的视频格式
* 为EXCLUDE_VIDEO可上传除视频格式外的所有支持的文件格式
*/
uploadType: {
type: String,
default: 'ALL',
validator: (value: string) =>
['ALL', 'IMG', 'VIDEO', 'EXCLUDE_VIDEO'].includes(value)
},
/**
* 上传提示
*/
uploadTip: {
type: String,
default: ''
},
/**
* 上传列表 用于数据回显
*/
uploadList: {
type: Array as PropType<Record<string, unknown>[]>,
default: () => []
},
/**
* 上传数量限制 默认1
*/
limit: {
type: Number,
default: 1,
validator: (value: number) => value >= 1
},
/**
* 是否禁用上传 默认否
*/
disabled: {
type: Boolean,
default: false
},
/**
* 最大文件大小 默认2GB
*/
maxSize: {
type: Number,
default: 2
}
}Types
import type { ExtractPropTypes } from 'vue'
import componentProps from './props'
/**
* props类型
*/
export type Props = ExtractPropTypes<typeof componentProps>
/**
* emits类型
*/
export type Emits = {
'update:fileId': [value: string | number]
'update:linkUrl': [url: string]
onFileObj: [file: Record<string, any>]
onError: [error: Error | string]
}