解决vue+el使用this.$confirm,不能阻断代码往下执行

在Vue+ElementUI框架中,通过await优化this.$confirm弹窗,确保弹窗响应后再执行后续代码,避免同步问题。文章详细介绍了如何使用Promise和await实现这一功能。
该文章已生成可运行项目,

前言

在vue+element ui的前端框架中使用el的confirm弹窗,遇到一个问题,就是连续多个弹窗提示一些信息,要是点击确定继续向下执行,点击取消就退出整个方法。这时发现当代码执行到this.$confirm弹窗时,弹出弹窗后,继续执行了弹窗之后的代码,没有等到弹窗点击确定或是取消之后再执行。

具体解决

其实解决办法也很简单,因为this.$confirm也是一个promise方法,所以可以使用es6中的await等到返回结果。
await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。

......

if(await this.$confirm('是否保存修改?', '确认信息', {
   distinguishCancelAndClose: true,
   confirmButtonText: '保存',
   cancelButtonText: '取消'
 }).catch(() => {}) !== 'confirm') {
	return
}
// 点击取消退出方法,点击保存则继续往下执行
// 若没有await,在弹出弹窗的同时就会接着往下执行
this.doSaveInfo()
......

后记

看官方文档学习一定要看仔细,看明白。认真学习promise和await。

本文章已经生成可运行项目
<template> <div class="content"> <div class="breadcrumd header"> <BreadcrumbHeader> <template #breadcrumb> <el-breadcrumb-item v-if="!isEdit"> {{ $t('新增') }} </el-breadcrumb-item> <el-breadcrumb-item v-else> {{ $t('编辑') }} </el-breadcrumb-item> </template> <template #expand> <div class="btn"> <el-button v-preventReClick @click="back"> {{ $t('Back') }} </el-button> <el-button v-preventReClick type="primary" @click="sure"> {{ $t('确定') }} </el-button> </div> </template> </BreadcrumbHeader> </div> <div class="context"> <MyCard :title=" productCategory === 'opticalModule' ? $t('光模块组基础信息') : $t('产品模型基础信息') " > <FormModel ref="formModel" :type="type" :isEdit="isEdit" :isClassify="true" :needTitle="false" :engineerProduct="true" ></FormModel> </MyCard> <MyCard :title="$t('配置列表')" class="list"> <el-row> <el-col :span="8"> <el-input v-if="isEdit && productCategory !== 'opticalModule'" v-model.trim="condition" clearable class="config_input" :placeholder="$t('搜索')" @keyup.enter="enterSearch" @clear="enterSearch" > <template #suffix> <el-icon><Search /></el-icon> </template> </el-input> </el-col> <el-col :offset="12" :span="4" class="btn_col"> <el-button type="primary" style="margin-bottom: 12px" @click="addconfigData"> {{ $t('新增配置') }} </el-button> </el-col> </el-row> <DynamicTable ref="configTable" type="Virtual_Engineer_Product_Config" :needIndex="true" :tableData="configData" :needExpand="true" :needShowImg="['istatus']" :imgAddress="imgAddress" :formatDiction="['istatus', 'source']" :dictionTypes="['Virtual_Engineer_Product_Config']" :dynamicField="['config_name']" :dynamicSlotName="['action']" :toggleRow="expandChange" > <template #action="props"> <span v-if="props.row.source_data === 'manual' || props.row.source === 'custom'" class="action_btn" @click="deleteConfigData(props.row)" > {{ $t('删除') }} </span> </template> <template #expand="props"> <DynamicTable ref="productTable" :type=" productCategory === 'opticalModule' ? 'Virtual_Engineer_Optical_Module_Product_List' : 'Virtual_Engineer_Product_List' " :needIndex="true" :tableData="supplyData" :parentData="props.row" :needShowImg="['istatus']" :imgAddress="imgAddress" :formatDiction="['istatus', 'release_status']" :dictionTypes="[ productCategory === 'opticalModule' ? 'Virtual_Engineer_Optical_Module_Product_List' : 'Virtual_Engineer_Product_List', ]" :dynamicField="['supply_product', 'count']" :dynamicSlotName="['action']" @productChange="productChange" > <template #action="scoped"> <span v-if="parantData.source_data === 'manual' || parantData.source === 'custom'" class="action_btn" @click="deleteProductData(scoped.row)" > {{ $t('删除') }} </span> </template> </DynamicTable> <el-row v-if="showProductAdd" type="flex" justify="center" class="add_btn"> <el-col :span="24"> <div @click="addProductData"> <el-icon><Plus /></el-icon> <span>{{ $t('新增产品') }}</span> </div> </el-col> </el-row> </template> </DynamicTable> </MyCard> </div> </div> </template> <script> import BreadcrumbHeader from '@/components/BreadcrumbHeader'; import MyCard from '../components/MyCard.vue'; import DynamicTable from './engineerComponent/dynamicTable.vue'; import FormModel from './engineerComponent/normalForm.vue'; import { getEngineerProductConfigAPI, saveProductMappingConfigAPI, saveOpticalModuleProductInfoAPI, } from '@/apis/ptp.js'; import { Plus, Search } from '@element-plus/icons-vue'; import { each } from 'lodash'; import pinia from '@/store/pinia'; import { useProductMgmtStore } from '@/store/modules/productMgmt'; export default { components: { BreadcrumbHeader, MyCard, FormModel, DynamicTable, Plus, Search, }, setup() { const productStore = useProductMgmtStore(pinia); return { productStore, }; }, data() { return { type: '', isEdit: true, configData: [], condition: '', supplyData: [], engineerProduct: '', productCategory: '', parantData: {}, showProductAdd: true, imgAddress: { 'istatus': { Y: new URL('../images/Status/completed.png', import.meta.url).href, N: new URL('../images/Status/offline.png', import.meta.url).href, }, }, }; }, created() { this.isEdit = this.$route.query.id ? true : false; this.type = this.$route.query.type; this.productCategory = this.$route.query.productCategory; if (this.isEdit) { this.engineerProduct = this.$route.query.engineerProduct; this.getConfigTableData(); } this.productStore.setResetPage(false); }, methods: { enterSearch() { this.getConfigTableData(); }, addconfigData() { let index = this.$refs.configTable.dynamicIndex; this.configData.push({ dynamicIndex: index + 1, source: 'custom', 'source_data': 'manual', version: 1, istatus: 'Y', }); }, getConfigTableData() { let { engineerProduct, condition } = this; let params = { engineerProduct, condition, }; getEngineerProductConfigAPI({ params }) .then(res => { if (res.success) { this.configData = res.data; } }) .catch(() => { // catch空值 }); }, deleteConfigData(row) { this.$confirm(this.$t('确认删除'), this.$t('提示'), { confirmButtonText: this.$t('确定'), cancelButtonText: this.$t('取消'), type: 'warning', }) .then(() => { let tableData = this.configData.filter(v => v.dynamicIndex !== row.dynamicIndex); this.configData = tableData; }) .catch(() => { // catch空值 }); }, deleteProductData(row) { for (let i = 0; i < this.supplyData.length; i++) { if (this.supplyData[i].dynamicIndex === row.dynamicIndex) { this.supplyData.splice(i, 1); return; } } }, productChange(key, row) { each(this.supplyData, v => { if (key.value === v.supply_product && v.dynamicIndex !== row.dynamicIndex) { this.$message.error(this.applyLang('供应产品名称重复', 'Duplicate supply product name.')); row['supply_product'] = ''; return; } if (v.dynamicIndex === row.dynamicIndex) { v.istatus = key.status; v.comments = key.comments; v['release_status'] = key.releaseStatus; } }); }, expandChange(row) { this.parantData = row; if ((row.source_data && row.source_data === 'manual') || row.source === 'custom') { this.showProductAdd = true; } else { this.showProductAdd = false; } if (row.mapping_product_list) { this.supplyData = row.mapping_product_list; } else { row['mapping_product_list'] = []; this.supplyData = row.mapping_product_list; } }, addProductData() { if (this.productCategory === 'Server' && this.supplyData.length >= 1) { this.$message.warning( this.applyLang( '机型组只能配置一个产品', 'Only one product can be configured for a model group.', ), ); return; } let index = this.$refs.productTable.dynamicIndex; this.supplyData.push({ dynamicIndex: index + 1, }); }, back() { let pathList = this.$route.path.split('/'); let path = pathList.slice(0, pathList.length - 1).join('/'); this.$router.push(path); }, isRepeat() { let result = true; const newArr = this.configData.map(item => item.config_name); each(newArr, (val, index) => { if (val && newArr.indexOf(val) !== index) { this.$message.error( this.applyLang( `序号${index + 1}配置名称重复`, `No. ${index + 1}: Duplicate configuration name.`, ), ); result = false; } }); return result; }, verifyConfig() { let result = true; let flag = true; const tableData = this.configData.filter(v => v.source === 'custom'); if (!this.isRepeat()) { return (result = false); } // eslint-disable-next-line consistent-return each(tableData, val => { if (!val.config_name) { this.$message.error( this.applyLang( `序号${val.dynamicIndex + 1}配置名称为空`, `No. ${val.dynamicIndex + 1} Configuration name is empty.`, ), ); return (result = false); } else { if (val.mapping_product_list) { if (!flag) { return (result = false); } each(val.mapping_product_list, v => { if (!v.supply_product || !v.count) { this.$message.error( this.applyLang( `序号${val.dynamicIndex + 1}产品配置有误`, `No. ${val.dynamicIndex + 1} Product Configuration Error`, ), ); result = false; flag = false; } }); } else { this.$message.error( this.applyLang( `序号${val.dynamicIndex + 1}配置产品列表为空`, `No. ${val.dynamicIndex + 1} The product list is empty.`, ), ); return (result = false); } return (result = false); } }); return result; }, assembleData() { let dataList = []; const tableData = this.configData.filter(v => v.source === 'custom'); each(tableData, val => { let mappingList = {}; if (val.id) { mappingList.id = val.id; } mappingList['config_name'] = val.config_name; if (val.mapping_product_list) { let productList = []; each(val.mapping_product_list, key => { productList.push({ count: key.count, 'supply_product': key.supply_product, }); }); mappingList['mapping_product_list'] = productList; } dataList.push(mappingList); }); return dataList; }, saveOpticalModuleProductInfoSure() { Promise.resolve(this.$refs.formModel?.reloadData()) .then(data => { if (data) { let result = this.verifyConfig(); // 校验配置列表 if (result) { this.saveOpticalModuleProductInfo(); } } }) .catch(() => { // catch空值 }); }, isSureSave(cb) { this.$confirm(this.$t('是否保存'), this.$t('提示'), { confirmButtonText: this.$t('确定'), cancelButtonText: this.$t('取消'), type: 'warning', }) .then(() => { if (cb) { cb(); } }) .catch(() => { // catch空值 }); }, saveOpticalModuleProductInfo() { this.isSureSave(() => { const baseInfo = this.$refs.formModel?.getFormData(); const params = { ...baseInfo, 'config_detail': this.assembleData(), }; if (!this.isEdit) { delete params.id; } saveOpticalModuleProductInfoAPI(params) .then(res => { if (res.success) { this.productStore.setResetPage(true); this.$message.success(this.$t('保存成功')); this.back(); } }) .catch(resData => { this.$message.error(resData.message); }); }); }, sure() { if (this.productCategory === 'opticalModule') { this.saveOpticalModuleProductInfoSure(); return; } let result = this.verifyConfig(); // 校验配置列表 if (result) { let data = this.assembleData(); this.isSureSave(() => { const params = { engineer_product: this.engineerProduct, mapping_config_list: data, }; saveProductMappingConfigAPI(params) .then(res => { if (res.success) { this.productStore.setResetPage(true); this.$message.success(this.$t('保存成功')); this.back(); } }) .catch(resData => { this.$message.error(resData.message); }); }); } }, }, }; </script> <style lang="less" scoped> .content { padding-bottom: 30px; } .header { margin-bottom: 20px; height: 40px; background-color: #fff; } .context { margin: 0 20px 20px; .list { margin-top: 12px; } } .action_btn { color: #526ecc; &:hover { cursor: pointer; font-weight: bold; } &:active { font-weight: normal; color: #adb0b8; } } .config_input { margin-bottom: 12px; input { height: 28px; } } .add_btn { margin-top: 7px; margin-bottom: 12px; .el-col { text-align: center; background-color: #eef0f5; height: 40px; line-height: 40px; color: #526ecc; span { margin-left: 10px; &:hover, &:active { font-weight: bold; } } &:hover { cursor: pointer; } } } .btn_col { text-align: right; display: flex; justify-content: flex-end; } </style> 点击确定按钮有的情景下生效
最新发布
11-04
<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" :on-remove="(file, fileList) => handleRemove('abnormalImageList', fileList)" :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" :on-remove="(file, fileList) => handleRemove('productImageList', fileList)" :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-remove="(file, fileList) => handleRemove('engHandoverImageList', fileList)" :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: '', lotList: [], eqpList: [], uploadInstances: {}, 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() { this.detailForm = { recordDate: '', workClass: '', workArea: '', abnormal: '', abnormalImage: '', abnormalImageList: [], product: '', productImage: '', productImageList: [], engHandover: '', engHandoverImage: '', engHandoverImageList: [], managerName: '', assigneeName: '', editAuth: false, submitAuth: false, auditAuth: false, assignAuth: false, id: '' }; this.lotList = []; this.eqpList = []; this.uploadInstances = {}; // Clear upload instances 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) { const formData = new FormData(); formData.append('file', options.file); const controller = new AbortController(); const uid = options.file.uid; this.uploadInstances[uid] = controller; request.post(process.env.VUE_APP_BASE_API + '/viewException/uploadImage', formData, { headers: { 'Content-Type': 'multipart/form-data' }, signal: controller.signal }) .then(response => { options.onSuccess({ ...response.data, uid: options.file.uid }); }) .catch(error => { if (error.name === 'CanceledError') { console.log('Request canceled'); } else { options.onError(error); } }); }, handleRemove(listName, file) { // 找到对应的文件索引 const index = this.detailForm[listName].findIndex(item => item.uid === file.uid); if (index !== -1) { this.detailForm[listName].splice(index, 1); } this.handleRemoveFile(file); }, handleRemoveFile(file) { const uid = file.uid; if (this.uploadInstances[uid]) { this.uploadInstances[uid].abort(); delete this.uploadInstances[uid]; } }, 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> 其中 <el-input type="textarea" v-model="detailForm.engHandover" :autosize="{ minRows: 2 }" placeholder="请输入工程师交接事项 或 选中粘贴图片" @paste="handlePaste($event, engHandoverImageRef)" :readonly="!detailForm.editAuth" ></el-input>这些无法贴图贴
08-09
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值