首先element-ui中的上传组件是这样的
数据结构:
{
action:“”//上传的连接
filelist:'‘’//选种的文件集合
}
<el-upload class="upload-demo" action="https://jsonplaceholder.typicode.com/posts/" :on-preview="handlePreview" :on-remove="handleRemove" :before-remove="beforeRemove" multiple :limit="3" :on-exceed="handleExceed" :file-list="fileList"> <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div></el-upload>
点击按钮后就自动根据action的地址上传,实际上是element-ui自动发送了post请求给action连接,但是我想要通过自己手动上传文件(图片/excel)
直接发送这个文件体
upload(){ this.request.post('/manage/uploadExcel',this.filelist).then(res=>{ alert(res.code) }) },
游览器发现无负载,并且前端已经自动发送了一次请求给action,如果把action参数取消,控制台还会报错
为了实现手动上传文件,需要添加<el-Upload>的属性 http-request
实现方法:因为直接只用filelist发送请求时无法携带的,所以就用自定义方法接受filelist的文件
<el-upload class="upload-demo" :on-preview="handlePreview" :on-remove="handleRemove" :before-remove="beforeRemove" multiple :action="null" :http-request="fileupdate" :limit="3" :on-exceed="handleExceed" :file-list="fileList"> <el-button size="small" type="primary" >导入excel数据 <i class="el-icon-circle-plus-outline"></i></el-button> </el-upload>
fileupdate方法
fileupdate(item){ this.model=item.file },
此时文件就已经赋值给自定义的数组model
再次使用axios发送post请求
upload(){ this.request.post('/manage/uploadExcel',this.model).then(res=>{ alert(res.code) })
成功
第二种方法
关闭自动上传 手动按钮上传 :auto-upload=“false”
<el-upload class="upload-demo" action="" :on-preview="handlePreview" :on-remove="handleRemove" ref="upload" :before-remove="beforeRemove" :auto-upload="false" multiple :limit="3" :on-success="handle_success" :on-exceed="handleExceed" :file-list="fileList"> <el-button slot="trigger" size="small" type="primary">选取文件</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button> <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
时间处理 axios提交请求
submitUpload() { //this.$refs.upload.submit(); let file = this.$refs.upload.uploadFiles.pop().raw;//这里获取上传的文件对象 let formData = new FormData(); formData.append("file",file); this.request.post("/app/uploadFiles",formData).then(res=>{ this.$message.success(res.data) })},
其中如果图片是上传oss
**:on-success=“handle_success”**可以写入上传成功的逻辑
//和axios一样的回调 handle_success(res) { console.log(res) this.$message.success('图片上传成功') },
自动上传中,可以使用header属性为action地址添加请求头
let headers=reactive( { Authorization: localStorage.getItem("token") });
2023.vue3 element plus 更新…因为element ui快停止维护了,所以这里记录,upload组件实现都都多个文件文件一次请求上传(element 默认的多选上传是多次请求上传的)
<el-upload :limit="4" ref="upload" class="upload-files" action="" name="files" :on-exceed="handleExceed" multiple :auto-upload="false" :file-list="fileList" :on-success="uploadusccess" :on-change="handleChange" style="margin-top: 20px" > <template #trigger> <el-button type="primary">选择图片<el-icon><DocumentAdd /></el-icon></el-button> </template> <el-button style="margin-left: 10px" class="ml-3" type="success" @click="updateinterUpload"> 保存到<el-icon><Upload /></el-icon> </el-button> <template #tip> <div class="el-upload__tip"> 最多上传4张 </div> </template> </el-upload>
script
let fileList=ref([])const loading = ref(false)//加载动画const handleExceed=(files, fileList) =>{ ElMessage.warning(`当前限制选择 4 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);}const handleChange = (file, files) => { // file是当前上传的文件,files是当前选中的所有的文件, fileList.value = files console.log("当前选择文件"+files)}//上传const updateinterUpload = async () => { try { loading.value=true const formData = new FormData(); formData.append('name', 'myk'); fileList.value.forEach(item => { console.log(item.raw); formData.append('file', item.raw); });//检验是否赋值 console.log(formData.getAll('file')); // 发送请求,注意 headers: {'Content-Type': 'multipart/form-data'} const response = await request.post('/upload/imgs', formData); console.log(response); if (response.code === 200) { loading.value=false addformData.value.iimgUrl=response.data ElMessage.success("操作成功"); } else { ElMessage.error("操作失败"); } } catch (error) { console.error("上传失败", error); ElMessage.error("上传失败"); }};
ts版本
<template><el-upload:limit="5"class="upload-files"name="file":on-exceed="handleExceed"multiple:auto-upload="false":file-list="fileList":on-change="handleChange"style="margin-top: 20px"><template #trigger><el-button type="primary">选择图片<el-icon><DocumentAdd /></el-icon></el-button></template><el-button style="margin-left: 10px" class="ml-3" type="success" @click="updateInterUpload">保存到<el-icon><Upload /></el-icon></el-button><template #tip><div class="el-upload__tip">最多上传4张</div></template></el-upload></template><script lang="ts" setup>import { ref } from 'vue'import { ElMessage, UploadFile } from 'element-plus'import request from '@/utils/request' // 根据实际项目路径调整const props = defineProps({successAction: {type: Function,required: true}})let fileList = ref<UploadFile[]>([]) // 使用 UploadFile 类型const loading = ref(false)const handleExceed = (files: UploadFile[], fileList: UploadFile[]) => {ElMessage.warning(`当前限制选择 5 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)}const handleChange = (file: UploadFile, files: UploadFile[]) => {fileList.value = files // 更新 fileListconsole.log('当前选择文件', files) // 修正日志输出}const updateInterUpload = async () => {try {loading.value = trueconst formData = new FormData()fileList.value.forEach(item => {if (item.raw) {// 确保 item.raw 是文件对象formData.append('file', item.raw) // 正确添加文件对象到 FormData}})// 在控制台打印 FormData 中的文件,仅用于调试for (let [key, value] of formData.entries()) {console.log(`${key}: ${value}`)}// 发送包含文件的 FormData 到服务器const response = await request.post('/product/upload', formData, {headers: { 'Content-Type': 'multipart/form-data' }})// 处理响应if (response.code === 0) {loading.value = falseElMessage.success('操作成功')} else {ElMessage.error('操作失败')}} catch (error) {console.error('上传失败', error)ElMessage.error('上传失败')}}</script>