useFileUpload
文件上传管理Hook,提供文件列表管理、上传状态跟踪和预览功能。
前置依赖
依赖参数
| 参数名 | 类型 | 说明 |
|---|---|---|
env.vue.ref | <T>(value: T) => Ref<T> | Vue的ref函数 |
env.vue.shallowRef | <T>(value: T) => Ref<T> | Vue的shallowRef函数 |
env.vue.onUnmounted | (fn: () => void) => void | 组件卸载钩子 |
env.host.createObjectURL | Window['URL']['createObjectURL'] | 创建对象URL |
env.host.revokeObjectURL | Window['URL']['revokeObjectURL'] | 撤销对象URL |
环境要求
- Vue 3: Composition API
- 浏览器: 支持File API和URL.createObjectURL
函数签名
typescript
function useFileUpload(
initialFileList: FileUploadItem[],
asyncBeforeUpload: (file: File) => Promise<boolean> | boolean,
asyncUpload: (file: File) => Promise<string>,
asyncAfterUpload: (file: File, url: string) => Promise<void> | void,
env: UseFileUploadEnvironment
): UseFileUploadReturn
interface FileUploadItem {
uid: string
originFile: File
status: 'ready' | 'uploading' | 'success' | 'failed'
localPreview?: string
onlinePreview?: string
}
interface UseFileUploadReturn {
fileList: Ref<FileUploadItem[]>
clear: () => void
append: (files: File | File[]) => void
replaceAt: (index: number, file: File) => void
}参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
initialFileList | FileUploadItem[] | 是 | 初始文件列表 |
asyncBeforeUpload | (file: File) => Promise<boolean> | boolean | 是 | 上传前的异步处理函数,返回false可阻止上传 |
asyncUpload | (file: File) => Promise<string> | 是 | 文件上传的异步函数,返回上传后的URL |
asyncAfterUpload | (file: File, url: string) => Promise<void> | void | 是 | 上传完成后的异步处理函数 |
env | UseFileUploadEnvironment | 是 | 环境依赖对象 |
返回值
| 类型 | 说明 |
|---|---|
fileList | Ref<FileUploadItem[]> |
clear | () => void |
append | (files: File | File[]) => void |
replaceAt | (index: number, file: File) => void |
工作原理
初始化:
- 创建响应式的文件列表
- 为每个文件生成唯一UID
- 自动创建本地预览URL(通过URL.createObjectURL)
文件上传流程:
- 调用
asyncBeforeUpload进行上传前验证 - 如果返回false,文件状态设为
failed - 如果通过验证,状态设为
uploading - 调用
asyncUpload执行实际上传 - 上传成功后,状态设为
success,保存onlinePreview - 调用
asyncAfterUpload进行后续处理 - 如果上传失败,状态设为
failed
- 调用
文件管理:
append: 添加新文件并自动开始上传replaceAt: 替换指定位置的文件,撤销旧文件预览URLclear: 清空列表并撤销所有预览URL
资源清理:
- 组件卸载时自动撤销所有本地预览URL
- 替换或删除文件时自动清理对应的预览URL
使用示例
typescript
import { ref, shallowRef, onUnmounted } from 'vue'
import { useFileUpload } from 'zcw-shared/vue-hooks/browser/useFileUpload'
const { fileList, append, clear, replaceAt } = useFileUpload(
[],
async (file) => {
// 上传前验证
if (file.size > 10 * 1024 * 1024) {
return false // 阻止上传大于10MB的文件
}
return true
},
async (file) => {
// 执行上传
const formData = new FormData()
formData.append('file', file)
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
})
const data = await response.json()
return data.url
},
async (file, url) => {
// 上传后处理
console.log('上传成功', file.name, url)
},
{
vue: { ref, shallowRef, onUnmounted },
host: {
createObjectURL: URL.createObjectURL,
revokeObjectURL: URL.revokeObjectURL
}
}
)
// 添加单个文件
const fileInput = document.querySelector('input[type="file"]')
fileInput.addEventListener('change', (e) => {
const files = (e.target as HTMLInputElement).files
if (files && files.length > 0) {
append(files[0])
}
})
// 批量添加文件
append([file1, file2, file3])
// 替换文件
replaceAt(0, newFile)
// 清空列表
clear()