使用el-upload组件遇到的坑。
1.第一种感觉最好,首先多个文件是一个http请求,另外还可以传除文件外其他的参数,但是没有进度条了。
发送请求的部分没有注释的部分是我分装了调后台的api,注释的部分是直接调。
注意如果使用自定义提交http-request,则on-success和on-error这两个钩子函数会不起作用,另外点击事件submitUpload中的this.$refs.uploadFiles.submit();是必须的,个人感觉是先将所有的文件给el-form处理,
我发先执行this.$refs.uploadFiles.submit();会多次执行handleUpload函数,次数与要上传文件的个数一样。
fileList: [], files: []要在data中先定义好,file是在form默认有的,是选进来的一个文件。action此时是无用的,但是必须要设置。
<template> <el-form> <div class="drop-upload-container"> <el-form-item :label-width="formLabelWidth"> <el-upload multiple drag ref="uploadFiles" :action="action" :limit="limit" :auto-upload="autoUpload" :accept="accept" :before-upload="beforeUploadFile" :on-remove="handleRemove" :on-change="fileChange" :on-exceed="exceedFile" :http-request="handleUpload" :file-list="fileList" > <i class="el-icon-upload"></i> <div class="el-upload__text"> {{ $t(‘upload.uploadText‘) }} <em>{{ $t(‘upload.clickUpload‘) }}</em> </div> <div class="el-upload__tip" slot="tip">{{ $t(‘upload.uploadFileType‘) }}</div> </el-upload> </el-form-item> <el-form-item class="item-container"> <el-button size="small" type="primary" @click.native="submitUpload" >{{ $t(‘buttonTitle.okTitle‘) }}</el-button> <el-button size="small" @click.native="uploadCancle">{{ $t(‘buttonTitle.cancleTitle‘) }}</el-button> </el-form-item> </div> </el-form> </template> <script> import { stringFormat } from "@/utils/stringutils"; import axios from "axios"; import { uploadFilesReq } from "@/api/upload"; export default { name: "Upload", props: { action: { required: true, type: String }, limit: { required: true, type: Number }, autoUpload: { type: Boolean, default: false }, accept: { required: true, type: String } }, data() { return { formLabelWidth: "80px", userIds: sessionStorage.getItem("userid"), fileList: [], files: [] }; }, methods: { // 文件超出个数限制时的钩子 exceedFile(files, fileList) { console.log("===exceed==="); let limit_num = `${this.limit}`; let total_num = `${files.length + fileList.length}`; this.$notify.warning({ title: this.$i18n.t("dialogTitle.dialogWarningTitle"), //message: `只能选择 ${this.limit} 个文件,当前共选择了 ${files.length + fileList.length} 个` message: stringFormat( this.$i18n.t("uploadDialogMsg.uploadFilesLimit"), [`${this.limit}`, `${files.length + fileList.length}`] ) }); }, // 文件状态改变时的钩子 fileChange(file, fileList) { console.log("===change==="); }, // 上传文件之前的钩子, 参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传 beforeUploadFile(file) { console.log("before upload"); console.log(file); let extension = file.name.substring(file.name.lastIndexOf(".") + 1); const isAcceptFiles = extension === "xlsx" || extension === "vue" || extension === "png" || extension === "PNG"; if (!isAcceptFiles) { this.$notify.warning({ title: this.$i18n.t("dialogTitle.dialogWarningTitle"), message: this.$i18n.t("uploadDialogMsg.uploadFilesType") }); } let size = file.size / 1024 / 1024; const isAcceptSize = size < 10; if (!isAcceptSize) { this.$notify.warning({ title: this.$i18n.t("dialogTitle.dialogWarningTitle"), message: this.$i18n.t("uploadDialogMsg.uploadFilesSize") }); } return isAcceptFiles && isAcceptSize; }, // 点击x时执行的钩子函数 handleRemove(file, fileList) { console.log("===remove==="); }, handleUpload(raw) { this.files.push(raw.file); }, submitUpload() { this.$refs.uploadFiles.submit(); let fd = new FormData(); fd.append("userIds", this.userIds); this.files.forEach(file => { fd.append("file", file, file.name); }); let config = { headers: { "Content-Type": "multipart/form-data" } }; uploadFilesReq(fd, config) .then(res => { console.log("===upload rep==="); console.log(res); if (res.data.status === "success") { this.$notify.success({ title: this.$i18n.t("dialogTitle.dialogSuccessTitle"), message: this.$i18n.t("uploadDialogMsg.uploadFilesSuccess") }); } else { this.$notify.error({ title: this.$i18n.t("dialogTitle.dialogErrorTitle"), message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed") }); } }) .catch(err => { console.log("===upload error==="); console.log(err); this.$notify.error({ title: this.$i18n.t("dialogTitle.dialogErrorTitle"), message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed") }); }); // axios // .post("/uploadFiles/pc/job/uploadFile", fd, config, { // timeout: 60000 * 3 // }) // .then(res => { // if (res.data.status === "success") { // this.$notify.success({ // title: this.$i18n.t("dialogTitle.dialogSuccessTitle"), // message: this.$i18n.t("uploadDialogMsg.uploadFilesSuccess") // }); // }else{ // this.$notify.error({ // title: this.$i18n.t("dialogTitle.dialogErrorTitle"), // message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed") // }); // } // }) // .catch(err => { // this.$notify.error({ // title: this.$i18n.t("dialogTitle.dialogErrorTitle"), // message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed") // }); // }); }, uploadCancle() { console.log("===Cancle==="); this.$refs.uploadFiles.clearFiles(); } } }; </script> <style scoped> .excel-upload-input { display: none; z-index: -9999; } .drop { border: 2px dashed #bbb; width: 600px; /* height: 160px; */ line-height: 160px; margin: 0 auto; font-size: 24px; border-radius: 5px; text-align: center; color: #bbb; position: relative; } .drop-upload-container { width: 450px; } .item-container { margin: 0 auto; /* text-align: center; */ padding-left: 80px; } </style>
上传文件调用后台api的封装
import Axios from ‘@/axios‘ export function uploadFilesReq(fd, config) { return Axios.post("/uploadFiles/pc/job/uploadFile", fd, config, { timeout: 60000 * 3 }); }
上传文件组件的调用
<template> <div class="app-container"> <upload :action="action" :limit="limitNum" :accept="accept" :auto-upload="autoUpload" /> </div> </template> <script> // import Upload from "@/components/Upload"; import Upload from "./upload"; export default { name: ‘UploadFiles‘, components: { Upload }, data() { return { action: ‘/uploadFiles/pc/job/uploadFile‘, limitNum: 3, accept: ".xlsx,.vue,.png,PNG", autoUpload: false } }, methods: { } } </script>
2.第二中每个文件都会发送一个请求,并且不能加其他的参数,但是有进度条。
action此时有用的,必须要设置,on-success和on-error这两个钩子函数会起作用
<template> <el-form> <div class="drop-upload-container"> <el-form-item :label-width="formLabelWidth"> <el-upload multiple drag ref="uploadFiles" :action="action" :limit="limit" :auto-upload="autoUpload" :accept="accept" :before-upload="beforeUploadFile" :on-remove="handleRemove" :on-change="fileChange" :on-exceed="exceedFile" :on-success="handleSuccess" :on-error="handleError" :file-list="fileList" > <i class="el-icon-upload"></i> <div class="el-upload__text"> {{ $t(‘upload.uploadText‘) }} <em>{{ $t(‘upload.clickUpload‘) }}</em> </div> <div class="el-upload__tip" slot="tip">{{ $t(‘upload.uploadFileType‘) }}</div> </el-upload> </el-form-item> <el-form-item class="item-container"> <el-button size="small" type="primary" @click.native="submitUpload" >{{ $t(‘buttonTitle.okTitle‘) }}</el-button> <el-button size="small" @click.native="uploadCancle">{{ $t(‘buttonTitle.cancleTitle‘) }}</el-button> </el-form-item> </div> </el-form> </template> <script> import { stringFormat } from "@/utils/stringutils"; import axios from ‘axios‘ export default { name: "Upload", props: { action: { required: true, type: String }, limit: { required: true, type: Number }, autoUpload: { type: Boolean, default: false }, accept: { required: true, type: String } }, data() { return { formLabelWidth: "80px", userIds: sessionStorage.getItem("userid"), fileList: [], files: [] }; }, methods: { // 文件超出个数限制时的钩子 exceedFile(files, fileList) { let limit_num = `${this.limit}`; let total_num = `${files.length + fileList.length}`; this.$notify.warning({ title: this.$i18n.t("dialogTitle.dialogWarningTitle"), message: stringFormat(this.$i18n.t("uploadDialogMsg.uploadFilesLimit"), [`${this.limit}`, `${files.length + fileList.length}`] ) }); }, // 文件状态改变时的钩子 fileChange(file, fileList) { console.log("===change==="); }, // 上传文件之前的钩子, 参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传 beforeUploadFile(file) { console.log("before upload"); console.log(file); let extension = file.name.substring(file.name.lastIndexOf(".") + 1); const isAcceptFiles = extension === "xlsx" || extension === "vue" || extension === "png" || extension === "PNG"; if (!isAcceptFiles) { this.$notify.warning({ title: this.$i18n.t("dialogTitle.dialogWarningTitle"), message: this.$i18n.t("uploadDialogMsg.uploadFilesType") }); } let size = file.size / 1024 / 1024; const isAcceptSize = size < 10; if (!isAcceptSize) { this.$notify.warning({ title: this.$i18n.t("dialogTitle.dialogWarningTitle"), message: this.$i18n.t("uploadDialogMsg.uploadFilesSize") }); } return isAcceptFiles && isAcceptSize; }, // 点击x时执行的钩子函数 handleRemove(file, fileList) { console.log("===remove==="); }, // 文件上传成功时的钩子 handleSuccess() { this.$notify.success({ title: this.$i18n.t("dialogTitle.dialogSuccessTitle"), message: this.$i18n.t("uploadDialogMsg.uploadFilesSuccess") }); }, // 文件上传失败时的钩子 handleError(err, file, fileList) { this.$notify.error({ title: this.$i18n.t("dialogTitle.dialogErrorTitle"), message: this.$i18n.t("uploadDialogMsg.uploadFilesFailed") }); }, handleUpload(raw) { this.files.push(raw.file); }, submitUpload() { console.log(this.form.userIds); this.$refs.uploadFiles.submit(); }, uploadCancle() { console.log("=========uploadFile========="); this.$refs.uploadFiles.clearFiles(); } } }; </script> <style scoped> .excel-upload-input { display: none; z-index: -9999; } .drop { border: 2px dashed #bbb; width: 600px; /* height: 160px; */ line-height: 160px; margin: 0 auto; font-size: 24px; border-radius: 5px; text-align: center; color: #bbb; position: relative; } .drop-upload-container { width: 450px; } .item-container { margin: 0 auto; /* text-align: center; */ padding-left: 80px; } </style>
原文地址:https://www.cnblogs.com/wang-liang-blogs/p/12101371.html
时间: 2024-08-07 02:31:59