Vue 3 + React 实现单文件和多文件上传
文件上传是前端开发中的常见功能,涵盖限制文件大小、显示上传进度、支持拖拽及文件类型校验等场景。
一、Vue 3 原生实现
1.1 单文件上传
使用原生方式实现单文件上传。
<template>
<div>
<!-- 文件选择框 -->
<input type="file" @change="handleFile" />
<!-- 上传按钮 -->
<button @click="upload" :disabled="!file">上传</button>
<!-- 预览文件名 -->
<p v-if="file">已选择:{{ file.name }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
const file = ref(null)
// 监听文件选择事件
const handleFile = (e) => {
file.value = e.target.files[0]
}
// 上传文件到服务器
const upload = async () => {
if (!file.value) return
const formData = new FormData()
formData.append('file', file.value)
await fetch('/api/upload', {
method: 'POST',
body: formData
})
}
</script>
注意细节:
e.target.files[0]获取第一个选中的文件,如需多选需添加multiple属性。FormData对象会自动设置Content-Type边界值。
1.2 多文件上传
改动不大,主要处理多个文件列表。
<template>
<div>
<input type="file" multiple @change="handleFiles" />
<button @click="upload" :disabled="!files.length">批量上传</button>
<ul>
<li v-for="f in files" :key="f.name">{{ f.name }}</li>
</ul>
</div>
</template>
<script setup>
import { ref } from 'vue'
const files = ref([])
// 获取选中的多个文件
const handleFiles = (e) => {
files.value = Array.from(e.target.files)
}
// 批量上传多个文件
const upload = async () => {
if (!files.value.length) return
const formData = new FormData()
// 注意:这里要用相同的字段名 'files',后端才能用 List/MultipartFile[] 接收
files.value.forEach(f => formData.append('files', f))
await fetch('/api/upload/multiple', {
method: 'POST',
body: formData
})
}
</script>
注意后端接收时,前端 append 的字段名需与后端参数名一致。
二、Vue 3 + Element Plus 实现
使用组件库可简化样式和交互逻辑。
2.1 单文件上传
<template>
<el-upload action="/api/upload" :on-success="handleSuccess" :on-error="handleError" :show-file-list="false">
<el-button type="primary">选择文件</el-button>
</el-upload>
</template>
<script setup>
// 上传成功回调
const handleSuccess = (res) => {
ElMessage.success('上传成功')
}
// 上传失败回调
const handleError = () => {
ElMessage.error('上传失败')
}
</script>
action 为必填项。:show-file-list="false" 用于隐藏已上传文件列表。
2.2 多文件上传
<template>
<el-upload
action="/api/upload"
:file-list="fileList"
:on-success="handleSuccess"
:on-remove="handleRemove"
:on-exceed="handleExceed"
:limit="5"
multiple
>
<el-button type="primary">选择文件</el-button>
<template #tip>
<div>支持 jpg、png、pdf 格式,单个文件不超过 10MB</div>
</template>
</el-upload>
</template>
<script setup>
import { ref } from 'vue'
const fileList = ref([])
// 文件数量超出限制了
const handleExceed = () => {
ElMessage.warning('最多只能上传 5 个文件')
}
// 手动移除了某个文件
const handleRemove = (file) => {
console.log('移除了:', file.name)
}
// 单个文件上传成功的回调
const handleSuccess = (res, file) => {
ElMessage.success(`${file.name} 上传成功`)
}
</script>


