Upload 上传
文件上传。支持点击与拖拽、单个与批量、自动与手动提交。
基础用法
将文件拖到此处,或 点击选择支持单个或批量上传,单张不超过 5MB
vue
<script setup>
import { ref } from 'vue'
const files = ref([])
</script>
<template>
<SrUpload
v-model="files"
action="/api/upload"
accept="image/*"
:max-size="5"
tip="支持单个或批量上传,单张不超过 5MB"
/>
</template>accept 与 max-size 不是安全措施——它们只是提前拦下明显的错误。 真正的校验必须在服务端做:客户端传什么都由客户端决定,改一个 accept 就能绕过。
拖拽上传
将文件拖到此处,或 点击选择拖拽文件到这里,或点击选择
vue
<SrUpload v-model="files" drag multiple action="/api/upload" />拖拽区同时响应整片区域,而不是只有那个小图标可点—— 这符合用户对「拖到这里」的直觉。
尺寸与类型限制
将文件拖到此处,或 点击选择最多 3 个文件,单个不超过 10MB
vue
<SrUpload accept=".pdf,.docx" :max-size="10" :limit="3" multiple />accept 用扩展名时注意:浏览器只做粗略匹配, 用户仍可通过「所有文件」选项选到别的类型。所以服务端校验不可省。
手动提交
auto-upload="false" 时,选中的文件不会立即上传, 而是先进入待上传列表,由宿主在合适时机调用 submit()。
将文件拖到此处,或 点击选择选好文件后点下方按钮上传
vue
<script setup>
import { ref } from 'vue'
const uploadRef = ref()
const files = ref([])
</script>
<template>
<SrUpload ref="uploadRef" v-model="files" :auto-upload="false" multiple />
<SrButton variant="primary" @click="uploadRef.submit()">开始上传</SrButton>
</template>何时该用手动提交
表单页里混着「文件」与「其他字段」时,通常是手动提交更合适—— 用户还没填完表单,文件就已经传到服务器上了,会产生一堆孤儿文件。
自定义上传
http-request 接管上传过程,用于需要签名、分片、或走 WebSocket 的场景。
将文件拖到此处,或 点击选择走自定义上传逻辑
vue
<script setup>
function myRequest({ file, onProgress, onSuccess, onError }) {
// 自行处理上传,并在适当时机回调:
// 模拟进度
onProgress(50)
setTimeout(() => onSuccess({ url: 'https://example.com/file.png' }), 600)
}
</script>
<template>
<SrUpload :http-request="myRequest" />
</template>必须调用 onSuccess 或 onError,否则该文件会永远停在「上传中」—— 组件无从知道外部逻辑是成功还是失败。
上传前拦截
before-upload 返回 false 会取消这次上传;返回一个 File 则替换待上传的文件(压缩图片、改名等场景)。
将文件拖到此处,或 点击选择
vue
<script setup>
function checkFile(file) {
if (file.name.includes('测试')) {
return false // 取消
}
return true
}
</script>
<template>
<SrUpload :before-upload="checkFile" />
</template>事件
将文件拖到此处,或 点击选择
最近结果:(尚未触发)
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue | SrUploadFile[] | 文件列表变化 |
success | (file) | 单个文件上传成功 |
error | (file, message) | 上传失败,第二个参数是错误信息 |
remove | (file) | 移除文件 |
exceed | (reason, file) | 超出限制,reason 为 'limit' / 'size' / 'type' / 'accept' |
error 是两个参数
失败信息同时存在于 file.message 和第二个参数里。
两个都给是有原因的:file 对象在列表渲染时更好用(能直接拿到文件名), 而 message 单独传参在只关心错误文案时更省事。
如果你从旧版本升级,注意第二个参数此前是 undefined—— 现在能正确拿到了。
Props
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue | SrUploadFile[] | [] | 文件列表 |
action | string | — | 上传地址 |
headers | Record<string, string> | — | 请求头(如鉴权 token) |
data | Record<string, string> | — | 随文件一起提交的额外字段 |
fieldName | string | 'file' | 文件字段名 |
accept | string | — | 接受的文件类型(非安全措施) |
limit | number | — | 最多几个文件 |
maxSize | number | — | 单文件大小上限(MB) |
multiple | boolean | false | 是否支持多选 |
drag | boolean | false | 是否启用拖拽上传 |
autoUpload | boolean | true | 选中后是否立即上传 |
disabled | boolean | false | 是否禁用 |
showFileList | boolean | true | 是否显示文件列表 |
tip | string | — | 提示文本 |
beforeUpload | (file) => boolean | File | Promise<...> | — | 上传前拦截,可返回新文件替换 |
httpRequest | (options) => void | — | 自定义上传实现 |
实例方法
| 方法 | 说明 |
|---|---|
submit() | 提交全部待上传文件(auto-upload="false" 时使用) |
clearFiles() | 清空文件列表 |
无障碍
- 触发区是
<button>语义,可键盘聚焦与触发 - 拖拽是增强而非唯一途径——键盘用户与移动端用户都能通过点击完成上传
- 上传失败的原因以文本呈现(而非仅用红色图标), 读屏软件能播报出具体哪里不合格