el-upload 多文件上传的研究 knowledgeSum page
需求,多文件上传,并且不要自动上传,就是选好了之后再一次性上传
后台接收
新增的时候:传file字段,注意要用formData
编辑的时候:传fileName filePath字段
编辑的时候又新增,那么就传三个字段
F12如下图
解决办法:
首先将upaload 改为false,意思为手动上传
然手在onchange的时候调用方法,将参数fileList里面遍历
initFileList(fileList){ //将fileList进行分组,分成之前上传过的和刚刚上传的 let fileNameArr=[],filePathArr=[];//修改addFields里面的fileName和filePath用 let thisFile=[];//files,修改addFields里面的file用 for(let item of fileList){ if(item.status == "success"){ fileNameArr.push(item.name) filePathArr.push(item.url) }else { if(item.raw!=undefined){ thisFile.push(item.raw) } } } return { [this.mergeOptions.fileName]:fileNameArr.join(','), [this.mergeOptions.filePath]:filePathArr.join(','), [this.field]:thisFile } // console.log({fileName:fileNameArr.join(','),filePath:filePathArr.join(',')},thisFile) //this.addFields = Object.assign({},this.addFields,obj) },
删除的时候
同样的调用传入的onMove事件,但是这个复用存在一点问题,所以我还是在vue文件写一个函数传入进来
//create的时候写一个函数到js中,删除的时候会调用moRemove this.addFormInfos.children.find(item=>item.field == 'files').options.onRemove= this.onRemove onRemove(file,fileList){ this.initFileList(fileList) }, initFileList(fileList){ //将fileList进行分组,分成之前上传过的和刚刚上传的 let fileNameArr=[],filePathArr=[];//修改addFields里面的fileName和filePath用 let thisFile=[];//files,修改addFields里面的file用 for(let item of fileList){ if(item.status == "success"){ fileNameArr.push(item.name) filePathArr.push(item.url) }else { if(item.raw!=undefined){ thisFile.push(item.raw) } } } let obj = { fileName:fileNameArr.join(','), filePath:filePathArr.join(','), files:thisFile } // console.log({fileName:fileNameArr.join(','),filePath:filePathArr.join(',')},thisFile) this.addFields = Object.assign({},this.addFields,obj) },
调用组件代码:
{ label: "alarm_label_appendix", field: "files", type: "SelfUploadMultip", options: { "header":{ 'content-type':'multipart/form-data' }, //"action":process.env.VUE_APP_URL2+DcomApi.uploadSohDevicePredict, "btnTitle":"app_button_selectUpload", // 选择上传 "placeholder": "app_placeholder_input", "autoUpload":false, "format": ['docx', 'xlsx'], "accept":".docx,.xlsx", "fileSize": 1, "showFileList" : true, "tips":"(提示:只能上传不超过1MB的文件)",//(提示:只能上传不超过1MB的py文件) "fileList" : [], "onRemove" : (file,fileList) => { //当删除已上传的文件时 //this.addFields.scriptPath = ""; console.log(file,fileList) }, "fileName":'fileName', "filePath":'filePath', "limit":10 // showField: "fileName" } },
完整的组件代码
<template> <el-upload class="upload-demo" :action="typeof mergeOptions.action === 'function'?mergeOptions.action(data):mergeOptions.action" :limit="mergeOptions.limit" :multiple="mergeOptions.multiple" :accept="mergeOptions.accept" :data="mergeOptions.data" :headers="typeof mergeOptions.headers === 'function'?mergeOptions.headers(data, requestHeader):mergeOptions.headers" :file-list="fileList" :show-file-list="mergeOptions.showFileList" :auto-upload="mergeOptions.autoUpload" :on-change="handleChange" :on-process="handleUploadProcess" :on-success="handleUploadSuccess" :before-upload="beforeFileUpload" :on-exceed="handleExceed" :on-error="handleUploadError" :style="{float:mergeOptions.float}" :on-remove="mergeOptions.onRemove" :before-remove="mergeOptions.beforeRemove" ref="upload" v-if="mergeOptions.isShow"> <el-button :size="mergeOptions.btnSize" :type="mergeOptions.btnType">{{$_c.getI18n(this.$t(`message.${mergeOptions.btnTitle}`))}}</el-button> <div slot="tip" class="el-upload__tip" v-if="mergeOptions.showTips">{{mergeOptions.tips}}</div> </el-upload> </template> <script> const defaultOptions = { isShow: true, showTips:true, autoUpload:true, showFileList:true, tips: '', btnSize: 'small', btnType: 'primary', btnTitle: 'app_button_clickUpload', // 点击上传 action: 'https://jsonplaceholder.typicode.com/posts/', fileList: [], format: [], fileSize: 50, clearFiles: true, fileName:'fileName',//编辑的时候用的key filePath:'filePath',//编辑的时候用的key onRemove : (file,fileList) => {}, beforeRemove : (file,fileList) => {} } export default { name: "SelfUploadMultip", props: { field: { type: String, default: '' }, options: { type: Object, default: () => {} }, data: { type: Object, default: () => {} }, activeField:{ type:String, default:'' } }, data() { return { mergeOptions:Object.assign({},defaultOptions,this.options), requestHeader: {}, value:[], fileList:[] }; }, watch:{ data:{ handler(newVal,oldVal){ if(this.activeField && this.activeField !== this.field) return this.value = newVal[this.field] }, deep:true }, options:{ handler(newVal,oldVal){ this.mergeOptions = Object.assign({},defaultOptions,newVal) }, deep:true } }, methods: { validFile(file){ // const fileName = file.name // const fileType = fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length) // if (fileType && ['png','jpg','jpeg'].indexOf(fileType) == -1) { // this.$message.error(this.$_c.getI18n(this.$t(`message.syscf_LC_selectPicture`))) // 只能上传png/jpg/jpeg格式的图片,请重新选择! // return true // } const isLt2M = file.size / 1024 / 1024 < this.mergeOptions.fileSize if (!isLt2M) { // this.$message.error(this.$_c.getI18n(this.$t(`message.syscf_LC_pictureSize1`))) // 上传图片大小不能超过 1MB! this.$message.error(`${this.$_c.getI18n(this.$t(`message.app_tips_fileSize`))} ${this.mergeOptions.fileSize}MB!`); // 上传文件大小不能超过 ${this.mergeOptions.fileSize}MB! return true } return false }, initFileList(fileList){ //将fileList进行分组,分成之前上传过的和刚刚上传的 let fileNameArr=[],filePathArr=[];//修改addFields里面的fileName和filePath用 let thisFile=[];//files,修改addFields里面的file用 for(let item of fileList){ if(item.status == "success"){ fileNameArr.push(item.name) filePathArr.push(item.url) }else { if(item.raw!=undefined){ thisFile.push(item.raw) } } } return { [this.mergeOptions.fileName]:fileNameArr.join(','), [this.mergeOptions.filePath]:filePathArr.join(','), [this.field]:thisFile } // console.log({fileName:fileNameArr.join(','),filePath:filePathArr.join(',')},thisFile) //this.addFields = Object.assign({},this.addFields,obj) }, handleChange(file, fileList) { if (this.validFile(file)) { //删除掉对应的fileList let index = fileList.findIndex(item=>item.uid == file.uid) if(index>-1){ fileList.splice(index,1) } return false } if(!this.mergeOptions.autoUpload){ let obj = this.initFileList(fileList) // this.$emit('changeFields', {activeField:this.field,[this.field]: {file, fileList}},) this.$emit('changeFields',Object.assign({},obj,{activeField:this.field})) } }, handleUploadProcess(file,fileList){ this.mergeOptions.tips = this.$_c.getI18n(this.$t(`message.app_tips_uploading`)) // 上传中 }, handleUploadSuccess(response, file, fileList) { // console.log("handleUploadSuccess", response, JSON.parse(JSON.stringify(file)), JSON.parse(JSON.stringify(fileList))) if(this.mergeOptions.clearFiles) { this.$refs.upload.clearFiles() } if(this.mergeOptions.autoUpload){ this.$emit('changeFields', {[this.field]: response.data,response},) } }, handleUploadError(error, file, fileList) { // console.log("handleUploadError",error, JSON.parse(JSON.stringify(file)), JSON.parse(JSON.stringify(fileList))) this.mergeOptions.tips = this.$_c.getI18n(this.$t(`message.app_tips_uploadFailed`)) // 上传失败 this.$emit('changeFields', {[this.field]: ''},error) }, //上传之前验证文件格式和大小 beforeFileUpload(file) { let extensens = file.name.substring(file.name.lastIndexOf('.')+1); const isFormat = this.mergeOptions.accept.includes(file.type) && file.type != "" || this.mergeOptions.format.includes(extensens); const isOverSize = file.size / 1024 / 1024 < this.mergeOptions.fileSize; if (!isFormat) { this.$message.error(this.$_c.getI18n(this.$t(`message.app_tips_uploadFile`))+ this.mergeOptions.format.join('、')+ this.$_c.getI18n(this.$t(`message.app_tips_format`))); // 上传文件只能是'+ this.mergeOptions.format.join('、')+ '格式! } if (!isOverSize) { this.$message.error(`${this.$_c.getI18n(this.$t(`message.app_tips_fileSize`))} ${this.mergeOptions.fileSize}MB!`); // 上传文件大小不能超过 ${this.mergeOptions.fileSize}MB! } let isOther = true if(this.options.beforeFileUploadOther) { isOther = this.options.beforeFileUploadOther(file) } return isFormat && isOverSize && isOther; }, // 获取请求头 getRequestHeader() { let Authorization = cookies.get('access_token') ? { "Authorization": "Bearer " + cookies.get('access_token') } : {} let headers = { "language": window.lockr.get('lang')?(window.lockr.get('lang')=='cn'?"zh_CN":"en_US"):'zh_CN', } this.requestHeader = Object.assign(Authorization, headers) }, handleExceed(file, fileList) { this.$message.warning(`当前限制选择${this.mergeOptions.limit}个文件,本次选择了${file.length}个文件。`) }, initFileData(){ if(this.data[this.mergeOptions.fileName]){ let arr = this.data[this.mergeOptions.fileName].split(',') let resultArr = [] for(let i=0;i<arr.length;i++){ resultArr.push({ name:arr[i], url:this.data.filePath }) } this.fileList = resultArr } }, init() { this.getRequestHeader() this.initFileData() } }, mounted(){ this.init() //console.log(this.mergeOptions) } } </script>