element中el-upload的取消上传this.$refs.upload.abort();

本文介绍如何在Element UI的el-upload组件中,通过调用abort方法解决上传大文件(如超过800M)时取消上传后再上传失败的问题。文中提到在el-upload中加入ref属性并使用$refs.upload.abort()方法可以有效解决该问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在用element中的el-upload方法,并且使用el-progress进度条实现取消上传的功能时候,当点击上传后,进度条正常显示百分比的进度,但是当点击”取消“后,再继续点击”上传“后,发现无法上传,尤其是第一次上传大视频文件(超过800M以上)的时候,这个问题必现,后来查看element的API:
https://element.eleme.cn/#/zh-CN/component/upload

发现有一个abort取消上传请求的方法,在el-upload中加入

ref="upload"

后,在取消上传的时候,加入以下方法:

this.$refs.upload.abort();

就解决了上面的问题。

反思:当发现有一些问题,很难用常规的方法解决后,这个时候再去看API,说不定会得到不一样的思路,重视API,重视API,重视API。

<template> <div> <el-dialog :visible.sync="dialogVisible" width="70%" :show-close="false" :close-on-click-modal="false" append-to-body @open="handleOpen" @close="handleClose" > <template slot="title"> <div style="text-align: center; font-size: 22px;"> {{ title }} </div> </template> <el-form :model="detailForm" label-width="130px" v-loading="loading"> <el-row> <el-col :span="8"> <el-form-item label="日期:"> <el-input readonly v-model="detailForm.recordDate"></el-input> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="班别:"> <el-input readonly v-model="detailForm.workClass"></el-input> </el-form-item> </el-col> </el-row> <el-form-item label="异常机况:"> <el-table :data="eqpList" style="width: 100%" id="eqpTable"> <el-table-column prop="area" label="Area"></el-table-column> <el-table-column prop="eqpId" label="Eqp Id"></el-table-column> <el-table-column prop="eqpName" label="Eqp Name"></el-table-column> <el-table-column prop="eqpStatus" label="Eqp Status"></el-table-column> <el-table-column prop="eqpHour" label="Hour"></el-table-column> <el-table-column prop="eqpUser" label="User"></el-table-column> <el-table-column prop="comments" label="Comment"></el-table-column> </el-table> <el-input type="textarea" v-model="detailForm.abnormal" :autosize="{ minRows: 2 }" placeholder="请输入异常机况 或 选中粘贴图片" @paste="handlePaste($event, abnormalImageRef)" :readonly="!detailForm.editAuth" ></el-input> <el-upload ref="abnormalImageRef" v-model="detailForm.abnormalImageList" action="#" :http-request="handleHttpUpload" list-type="picture-card" :before-upload="beforeUpload" :on-success="() => uploadSuccess('abnormalImageList')" :on-error="uploadError" :accept="fileType.join(',')" :on-preview="handlePreview" :disabled="!detailForm.editAuth" > <i class="el-icon-plus"></i> </el-upload> </el-form-item> <el-form-item label="产片:"> <el-table :data="lotList" style="width: 100%" id="lotTable"> <el-table-column prop="eqp" label="机台"></el-table-column> <el-table-column prop="priority" label="Priority"></el-table-column> <el-table-column prop="lotId" label="Lot ID"></el-table-column> <el-table-column prop="maskTitle" label="Mask Title"></el-table-column> <el-table-column prop="dueDay" label="Due Day"></el-table-column> </el-table> <el-input type="textarea" v-model="detailForm.product" :autosize="{ minRows: 2 }" placeholder="请输入产片 或 选中粘贴图片" @paste="handlePaste($event, productImageRef)" :readonly="!detailForm.editAuth" ></el-input> <el-upload ref="productImageRef" v-model="detailForm.productImageList" action="#" :http-request="handleHttpUpload" list-type="picture-card" :before-upload="beforeUpload" :on-success="() => uploadSuccess('productImageList')" :on-error="uploadError" :accept="fileType.join(',')" :on-preview="handlePreview" :disabled="!detailForm.editAuth" > <i class="el-icon-plus"></i> </el-upload> </el-form-item> <el-form-item label="工程师交接事项:"> <el-input type="textarea" v-model="detailForm.engHandover" :autosize="{ minRows: 2 }" placeholder="请输入工程师交接事项 或 选中粘贴图片" @paste="handlePaste($event, engHandoverImageRef)" :readonly="!detailForm.editAuth" ></el-input> <el-upload ref="engHandoverImageRef" v-model="detailForm.engHandoverImageList" action="#" :http-request="handleHttpUpload" list-type="picture-card" :before-upload="beforeUpload" :on-success="() => uploadSuccess('engHandoverImageList')" :on-error="uploadError" :accept="fileType.join(',')" :on-preview="handlePreview" :disabled="!detailForm.editAuth" > <i class="el-icon-plus"></i> </el-upload> </el-form-item> <el-form-item label="课长:" v-if="detailForm.managerName !== null"> <el-input v-model="detailForm.managerName" readonly></el-input> </el-form-item> <el-form-item label="接班人:" v-if="detailForm.assigneeName !== null"> <el-input type="textarea" v-model="detailForm.assigneeName" readonly autosize></el-input> </el-form-item> </el-form> <template slot="footer"> <el-button type="primary" @click="save" v-if="detailForm.editAuth">保存</el-button> <el-button @click="closeDialog">取消</el-button> <el-button type="primary" @click="submit" v-if="detailForm.submitAuth">提交</el-button> <el-button type="primary" @click="audit" v-if="detailForm.auditAuth">审核</el-button> <el-button type="primary" @click="assign" v-if="detailForm.assignAuth">签核</el-button> </template> </el-dialog> <el-dialog :visible.sync="previewVisible" :show-close="false"> <img width="100%" :src="previewImageUrl" alt="Preview Image"/> </el-dialog> </div> </template> <script> import { getJournalForEdit, saveJournal, submitJournal, auditJournal, assignJournal, clearEditUser } from '@/api/mfgLog/area'; import request from '@/utils/request'; import {Message, MessageBox } from "element-ui"; import dayjs from 'dayjs'; import { getToken } from '@/utils/auth' export default { data() { return { loading: false, dialogVisible: false, title: '光罩厂制造部站点交接记录簿', fileType: ['image/jpeg', 'image/png', 'image/gif'], abnormalImageRef: null, engHandoverImageRef: null, productImageRef: null, previewVisible: false, previewImageUrl: '', detailForm: { recordDate: '', workClass: '', workArea: '', abnormal: '', lotList: [], eqpList: [], abnormalImage: '', abnormalImageList: [], product: '', productImage: '', productImageList: [], engHandover: '', engHandoverImage: '', engHandoverImageList: [], managerName: '', assigneeName: '', editAuth: false, submitAuth: false, auditAuth: false, assignAuth: false, id: '' }, timer: null }; }, mounted() { // 监听事件以重置计时器 window.addEventListener('keydown', this.resetTimer); window.addEventListener('mousemove', this.resetTimer); window.addEventListener('mouseenter', this.resetTimer); // 浏览器关闭事件 window.addEventListener('beforeunload', (e) => { this.userInactive(); }); }, beforeDestroy() { // 清除事件监听和计时器 window.removeEventListener('keydown', this.resetTimer); window.removeEventListener('mousemove', this.resetTimer); window.removeEventListener('mouseenter', this.resetTimer); clearTimeout(this.timer); }, methods: { handleOpen() { this.resetTimer(); }, handleClose() { clearTimeout(this.timer); }, resetTimer() { // 用户进行了操作,重置计时器 if (this.timer) { clearTimeout(this.timer); } this.startTimer(); }, startTimer() { // 设置5分钟后的无操作处理 this.timer = setTimeout(() => { // 用户5分钟内无操作,执行相关逻辑 if (this.dialogVisible) { this.userInactive(); } }, 5 * 60 * 1000); }, userInactive() { // 用户处于非活跃状态的逻辑处理 if (this.detailForm.editAuth) { this.save(); } this.closeDialog(); }, showDialog(row) { this.loading = true; getJournalForEdit(row).then(res => { Object.assign(this.detailForm, res.data); // 显示提示信息 if (!this.detailForm.editAuth && !this.detailForm.assignAuth && this.detailForm.editUser) { Message.warning({ message: "当前日志正在被 " + this.detailForm.editUserName + " 编辑", position: 'top', // 确保消息显示在页面顶部 duration: 5000 // 消息显示时间为 5 秒 }); return 0; } this.detailForm.abnormalImageList = []; if (this.detailForm.abnormalImage?.length > 0) { let abnormalList = this.detailForm.abnormalImage.split(","); for (let index in abnormalList) { this.detailForm.abnormalImageList.push({ url: abnormalList[index] }); } } this.detailForm.productImageList = []; if (this.detailForm.productImage?.length > 0) { let productList = this.detailForm.productImage.split(","); for (let index in productList) { this.detailForm.productImageList.push({ url: productList[index] }); } } this.detailForm.engHandoverImageList = []; if (this.detailForm.engHandoverImage?.length > 0) { let engHandoverList = this.detailForm.engHandoverImage?.split(","); for (let index in engHandoverList) { this.detailForm.engHandoverImageList.push({ url: engHandoverList[index] }); } } if (this.detailForm.lotList && Array.isArray(this.detailForm.lotList)) { this.lotList = this.detailForm.lotList; } else { this.lotList = []; // 否则初始化为空数组 } if (this.detailForm.eqpList && Array.isArray(this.detailForm.eqpList)) { this.eqpList = this.detailForm.eqpList; } else { this.eqpList = []; // 否则初始化为空数组 } this.title = "光罩厂制造部 " + this.detailForm.workArea + " 站点交接记录簿"; // 判断当前时间是否允许提交/审核日志 if (this.detailForm.submitAuth || this.detailForm.auditAuth) { // 白班18点30分之前不允许提交和审核 let authTime = this.detailForm.recordDate + " 18:30:00"; if ('N' == this.detailForm.workClass.substring(0, 1)) { // 晚班06点30分之前不允许提交和审核 authTime = dayjs(this.detailForm.recordDate).add(1, 'day').format("YYYY-MM-DD") + " 06:30:00"; } if (dayjs().isBefore(dayjs(authTime))) { this.detailForm.submitAuth = false; this.detailForm.auditAuth = false; } } // 父系统页面打开遮罩 window.parent.postMessage("open", '*'); this.dialogVisible = true; // 设置初始计时器 this.loading = false; }).catch(error => { console.log(error); this.loading = false; }); }, closeDialog() { clearEditUser({ id: this.detailForm.id }).catch(error => { Message.error(error.msg ? error.msg : error); }); this.$emit('close'); // 父系统页面关闭遮罩 window.parent.postMessage("close", '*'); this.dialogVisible = false; }, save() { this.detailForm.abnormalImage = this.detailForm.abnormalImageList.map(item => item.url).join(","); this.detailForm.productImage = this.detailForm.productImageList.map(item => item.url).join(","); this.detailForm.engHandoverImage = this.detailForm.engHandoverImageList.map(item => item.url).join(","); this.loading = true; saveJournal(this.detailForm).then(res => { this.loading = false; Message.success("保存成功"); this.closeDialog(); }).catch(error => { this.loading = false; }); }, submit() { MessageBox.confirm("确认要提交吗?", "提示", { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning', }).then(res => { this.detailForm.abnormalImage = this.detailForm.abnormalImageList.map(item => item.url).join(","); this.detailForm.productImage = this.detailForm.productImageList.map(item => item.url).join(","); this.detailForm.engHandoverImage = this.detailForm.engHandoverImageList.map(item => item.url).join(","); this.loading = true; submitJournal(this.detailForm).then(res => { this.loading = false; Message.success("提交成功"); this.closeDialog(); }).catch(error => { this.loading = false; Message.error(error.msg ? error.msg : error); }); }).catch(error => { console.log(error); }); }, audit() { MessageBox.confirm("确认要提交审核吗?", "提示", { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning', }).then(res => { this.detailForm.abnormalImage = this.detailForm.abnormalImageList.map(item => item.url).join(","); this.detailForm.productImage = this.detailForm.productImageList.map(item => item.url).join(","); this.detailForm.engHandoverImage = this.detailForm.engHandoverImageList.map(item => item.url).join(","); this.detailForm.lotList = this.detailForm.lotList this.detailForm.eqpList = this.detailForm.eqpList this.loading = true; auditJournal(this.detailForm).then(res => { this.loading = false; Message.success("审核成功"); this.closeDialog(); }).catch(error => { this.loading = false; Message.error(error.msg ? error.msg : error); }); }).catch(error => { console.log(error); }); }, assign() { MessageBox.confirm("确认要签核吗?", "提示", { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning', }).then(res => { this.loading = true; assignJournal({ id: this.detailForm.id }).then(res => { this.loading = false; Message.success("签核成功"); this.closeDialog(); }).catch(error => { this.loading = false; Message.error(error.msg ? error.msg : error); }); }).catch(error => { console.log(error); }); }, handleHttpUpload(options) { return process.env.VUE_APP_BASE_API + '/viewException/uploadImage' }, headers(){ return { "Authorization": 'Bearer ' + getToken() } }, beforeUpload(rawFile) { const imgType = this.fileType.includes(rawFile.type); if (!imgType) { Message.warning({ title: '温馨提示', message: '上传图片不符合所需的格式!', }); } return imgType; }, uploadSuccess(imageListName) { Message.success({ title: '温馨提示', message: '图片上传成功!', }); this.detailForm[imageListName].forEach(item => { if (item.url.indexOf("/api/") < 0) item.url = item.response.url; }); }, uploadError() { Message.error({ title: '温馨提示', message: '图片上传失败,请您重新上传!', }); }, handlePaste(event, uploadRef) { const items = (event.clipboardData || window.clipboardData).items; let file = null; if (!items || items.length === 0) { Message.error("当前浏览器不支持粘贴板"); return; } // 搜索剪切板items for (let i = 0; i < items.length; i++) { if (items[i].type.indexOf("image") !== -1) { file = items[i].getAsFile(); break; } } if (!file) { return; } uploadRef.handleStart(file); // 将粘贴过来的图片加入预上传队列 uploadRef.submit(); // 提交图片上传队列 }, handlePreview(file) { this.previewImageUrl = file.url; this.previewVisible = true; } } }; </script> <style scoped> .layout-padding-custom { padding: 20px; } .border-vxe-table { margin-top: 20px; } </style> 报错vue.runtime.esm.js:620 [Vue warn]: Error in v-on handler: "TypeError: reqs[uid].abort is not a function" found in ---> <ElUploadList> at packages/upload/src/upload-list.vue <ElUpload> at packages/upload/src/index.vue <ElFormItem> at packages/form/src/form-item.vue <ElForm> at packages/form/src/form.vue <ElDialog> at packages/dialog/src/component.vue <Detail> at src/views/mfgLog/area/detail.vue <Index> at src/views/mfgLog/area/index.vue <AppMain> at src/layout/components/AppMain.vue <Layout> at src/layout/index.vue <App> at src/App.vue <Root> warn @ vue.runtime.esm.js:620 logError @ vue.runtime.esm.js:1892 globalHandleError @ vue.runtime.esm.js:1887 handleError @ vue.runtime.esm.js:1847 invokeWithErrorHandling @ vue.runtime.esm.js:1870 invoker @ vue.runtime.esm.js:2187 invokeWithErrorHandling @ vue.runtime.esm.js:1862 Vue.$emit @ vue.runtime.esm.js:3897 click @ element-ui.common.js:28831 invokeWithErrorHandling @ vue.runtime.esm.js:1862 invoker @ vue.runtime.esm.js:2187 original._wrapper @ vue.runtime.esm.js:6951 vue.runtime.esm.js:1896 TypeError: reqs[uid].abort is not a function at VueComponent.abort (element-ui.common.js:29351:21) at VueComponent.abort (element-ui.common.js:29717:34) at doRemove (element-ui.common.js:29688:16) at VueComponent.handleRemove (element-ui.common.js:29695:9) at invokeWithErrorHandling (vue.runtime.esm.js:1862:26) at Proxy.invoker (vue.runtime.esm.js:2187:14) at invokeWithErrorHandling (vue.runtime.esm.js:1862:26) at Vue.$emit (vue.runtime.esm.js:3897:9) at click (element-ui.common.js:28831:37) at invokeWithErrorHandling (vue.runtime.esm.js:1862:26)
最新发布
08-08
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Web3&Basketball

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值