記錄時間
2020年10月27日 22點38分
前言
在使用element-ui上傳組件上傳多個文件時,出現多個文件對應着多個請求,比如你要上傳3個文件,那麼將請求3個後臺接口,這樣會無形之中增加了後臺系統的服務器壓力,因此只能前端代碼做修改,使得多個文件上傳只請求1次後臺接口。而搜索了相關文章,大部分都是講解了前端的代碼,而沒有添上後臺的代碼,因此本作者藉此將我完善的前後端代碼添出來供大家參考。
前端代碼
<template>
<div>
<el-upload
class="upload-demo"
drag
ref="upload"
:action="uploadAction"
:auto-upload="autoUpload"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:on-change="beforeUpload"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
:data="extraParam"
:headers="headers"
:limit="fileSizeLimit"
:file-list="fileList"
:on-exceed="handleExceed"
:accept="fileType"
multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">將文件拖到此處,或<em>點擊上傳</em></div>
<div class="el-upload__tip" slot="tip">
<span style="color: #FE6D68;">*</span>
{{promptMessage}}
</div>
</el-upload>
</div>
</template>
<script>
import {upload} from '@/utils/upload'
import {getToken} from '@/utils/tokenOperation'
export default{
name: 'FileUpload',
props: {
/* 上傳框提示 */
promptMessage: {
default: '只能上傳xls/xlsx文件',
type: String
},
/* 文件上傳路徑 */
uploadAction: {
default: '',
type: String
},
/* 文件類型 */
fileType: {
default: '.xlsx,.xls',
type: String
},
/* 限制最大文件上傳數 */
fileSizeLimit: {
default: 2,
type: Number
}
},
data() {
return {
/* 上傳時附帶的額外參數,返回是一個對象 */
extraParam: {},
/* 已上傳的文件列表 */
fileList: [],
/* 請求頭 */
headers: {
'strainpreservation': getToken()
},
/* 是否在選取文件後立即進行上傳 */
autoUpload: false,
}
},
methods:{
/* 文件列表移除文件成功時的鉤子 */
handleRemove(file, fileList) {
return this.successNotify(`已成功移除"${file.name}"文件`)
},
/* 處理上傳失敗時的勾子 */
handleUploadError(err, file, fileList) {
this.errorNotify(`文件上傳失敗`)
},
/* 文件刪除前的勾子 */
beforeRemove(file, fileList) {
return this.$confirm(`確定移除"${file.name}"文件嗎?`)
},
/* 上傳文件之前的鉤子 因設置了auto-upload爲false,如果使用before-upload,雖有提示,但是還是會請求服務器*/
beforeUpload(file,fileList) {
// 1、判斷文件名是否重複,不允許上傳相同文件
let existFile = fileList.slice(0, fileList.length - 1).find(f => f.name === file.name)
if(existFile){
fileList.pop()
this.warningNotify(file.name+" 文件已存在!")
}
// 2、獲取文件後綴
fileList.forEach(everyFile => {
const fileType = everyFile.name.substring(everyFile.name.lastIndexOf('.'))
if(this.fileType.search(fileType) === -1){
fileList.pop()
this.warningNotify("上傳文件的類型不正確"+"文件類型必須爲" + this.fileType + '')
}
})
this.fileList = fileList;
},
/* 文件超出個數限制時的鉤子 */
handleExceed(files, fileList) {
this.warningNotify(`當前限制選擇`+ this.fileSizeLimit +`個文件,本次選擇了 ${files.length} 個文件,已超出了文件最大上傳個數`)
},
/* 文件上傳成功時的鉤子 */
handleUploadSuccess(res, file, fileList) {
console.info(JSON.stringify(res))
},
/* 確定上傳 */
submitUpload() {
upload(this.uploadAction,this.fileList).then(res => {
this.fileList = []
});
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.el-upload__tip{
font-weight: bold;
font-size: 14px;
}
.upload_div{
padding: 10px 0px 20px 20px;
text-align: right;
box-sizing: border-box;
}
</style>
import axios from 'axios'
import { getToken } from '@/utils/tokenOperation'
export function upload(api, file) {
var data = new FormData()
file.forEach(everyFile => {
data.append("file",everyFile.raw)
})
const config = {
headers: {
'strainpreservation': getToken()
}
}
return axios.post(api, data, config)
}
1、getToken是自己封裝的從cookie中獲取token的方法
2、everyFile.raw就是File數據,大夥可以debug看看,或者使用console.info(everyFile)看看裏面的內容
* 結合前端的代碼做一些講解:
1、upload上傳組件的action屬性一定要寫
這是upload組件約定的,無論是否使用upload內部實現的上傳方式,這個action屬性是一定要寫的,要不然會報"沒有action屬性"的錯誤。
2、action-upload設置爲false,file-list屬性也一定要寫
action-upload設置爲false,是因爲不讓它自動上傳,因爲我們的頁面,很多時候都是當選擇完文件後,點擊按鈕才允許上傳的,而file-list屬性是存儲上傳的文件的信息。
3、當action-upload屬性設置爲false時,before-upload方法是失效的
當action-upload屬性設置爲false時,before-upload如果做文件大小、文件類型、文件重複等邏輯的判斷,假如文件類型錯誤,return false或者Promise. reject ()方法想終止上傳時,是終止不了的,還是會請求到服務器。因此需要使用on-onchange屬性來替換
後臺代碼
/**
* 導入培養基信息
* @param file
* @return
*/
@ApiOperation(value = "導入培養基信息",notes = "點擊頁面上的導入按鈕時請求的接口")
@PostMapping(value = "/importMediumInfo")
@PreAuthorize("@el.check('sys:medium:import')")
public BaseResultVO importMediumInfo(@RequestParam("file") MultipartFile[] file){
return iMediumInfoService.mediumFileUpload(file);
}
* 1、後臺我使用MultipartFile數組來接收前端FormData傳來的數據。業務層的邏輯我就不添出來了,因爲後臺我是使用的EasyExcel來實現的。