使用try-finally结构执行状态重置
原代码
const commitForm = async () => { btnLoading.value = true; isCommitted.value = true; //过滤出显示字段的列表 let showFieldsList = []; for (let comp of compList.value) { if (comp.isShow) { showFieldsList.push(comp); } } //必填校验 for (let comp of showFieldsList) { if (comp.isRequired && comp.isShow) { if (comp.type === "showPic") { if (comp.picUrl) { formData.value[comp.prop] = comp.picUrl; } } else if (comp.type === "subForm") { const subForm = comp.subForm; if (subForm) { // 子表单必填字段列表 let propList = []; for (let subComp of subForm) { if (subComp.isConfigRequired) { propList.push({ prop: subComp.prop, label: subComp.label, }); } } const subFormFillDataStr = formData.value[comp.prop]; const subFormFillDataArr = JSON.parse(subFormFillDataStr ?? "[]"); if (subFormFillDataArr.length === 0 && propList.length > 0) { message.error(`请填写子表单数据`); return; } for (let item of propList) { for (let subFormFillData of subFormFillDataArr) { if ((subFormFillData[item.prop] ?? "") === "") { message.warning(`${item.label}是必填字段`); return; } } } } } else if (comp.type === "checkBox") { if ( formData.value[comp.prop] == "others" || (Array.isArray(formData.value[comp.prop]) && formData.value[comp.prop].length === 0) || (formData.value[comp.prop] ?? "") === "" ) { message.warning(`${comp.label}是必填字段`); return; } if ( formData.value[comp.prop].includes("others") && !formData.value[comp.prop].some((item) => item.startsWith("others-")) ) { message.warning(`${comp.label}字段的其他选项勾选但未填写`); return; } } else if ((formData.value[comp.prop] ?? "") === "") { message.warning(`${comp.label}是必填字段`); return; } //校验手机号 if (comp.isValidateTel) { if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(comp.sensitiveInfoTxt)) { message.warning(`${comp.label}格式错误`); return; } } // 正则表达式校验 if (comp.regExp && comp.regExp !== "") { const res = validateCompValue(comp); if (!res) { return; } } //相等校验 if (comp.sameValueAsCompValue) { if ( formData.value[comp.prop] !== formData.value[comp.sameValueAsCompValue] ) { message.warning(`${comp.label}字段配置的两次输入内容不同`); return; } } } } const copyFormState = JSON.parse(JSON.stringify(formData.value)); for (let comp of compList.value) { if (["checkBox", "dataBind"].includes(comp.type)) { if (Array.isArray(copyFormState[comp.prop])) { copyFormState[comp.prop] = copyFormState[comp.prop].join(","); copyFormState[comp.prop] = rearrangeOthers(copyFormState[comp.prop]); } } if (comp.type === "dateTime") { if (copyFormState[comp.prop]) { copyFormState[comp.prop] = dayjs(copyFormState[comp.prop]).format( "YYYY-MM-DD HH:mm" ); } } } const res = await validateTryUpdateOrder( props.workConfCode, props.formWebUuid ); if (res === "covered") { return; } const params = { workConfCode: props.workConfCode, parentOrderId: route.query.orderId, subFormWebUuid: props.formWebUuid, }; SmartFormApi.subFormNewRecord(params, copyFormState) .then(async (result) => { if (result.data.code === 200) { message.success("已提交表单"); emit("updateFormStatus", "已完成"); } else { message.error(result.data.message); btnLoading.value = false; isCommitted.value = false; } }) .catch((err) => { console.error(err); btnLoading.value = false; isCommitted.value = false; }); };
需要一进入这个函数就给按钮置灰,防止重复提交,但是函数内部return很多。
如果给每个return前都加上恢复按钮正常功能,则会造成大量的工作量和代码冗余,且不利于后续扩展。
可以使用try-finally结构,将代码改为
const commitForm = async () => { btnLoading.value = true; isCommitted.value = true; try { //过滤出显示字段的列表 let showFieldsList = []; for (let comp of compList.value) { if (comp.isShow) { showFieldsList.push(comp); } } //必填校验 for (let comp of showFieldsList) { if (comp.isRequired && comp.isShow) { if (comp.type === "showPic") { if (comp.picUrl) { formData.value[comp.prop] = comp.picUrl; } } else if (comp.type === "subForm") { const subForm = comp.subForm; if (subForm) { // 子表单必填字段列表 let propList = []; for (let subComp of subForm) { if (subComp.isConfigRequired) { propList.push({ prop: subComp.prop, label: subComp.label, }); } } const subFormFillDataStr = formData.value[comp.prop]; const subFormFillDataArr = JSON.parse(subFormFillDataStr ?? "[]"); if (subFormFillDataArr.length === 0 && propList.length > 0) { message.error(`请填写子表单数据`); return; // 校验失败,退出执行 } for (let item of propList) { for (let subFormFillData of subFormFillDataArr) { if ((subFormFillData[item.prop] ?? "") === "") { message.warning(`${item.label}是必填字段`); return; // 校验失败,退出执行 } } } } } else if (comp.type === "checkBox") { if ( formData.value[comp.prop] == "others" || (Array.isArray(formData.value[comp.prop]) && formData.value[comp.prop].length === 0) || (formData.value[comp.prop] ?? "") === "" ) { message.warning(`${comp.label}是必填字段`); return; // 校验失败,退出执行 } if ( formData.value[comp.prop].includes("others") && !formData.value[comp.prop].some((item) => item.startsWith("others-")) ) { message.warning(`${comp.label}字段的其他选项勾选但未填写`); return; // 校验失败,退出执行 } } else if ((formData.value[comp.prop] ?? "") === "") { message.warning(`${comp.label}是必填字段`); return; // 校验失败,退出执行 } //校验手机号 if (comp.isValidateTel) { if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(comp.sensitiveInfoTxt)) { message.warning(`${comp.label}格式错误`); return; // 校验失败,退出执行 } } // 正则表达式校验 if (comp.regExp && comp.regExp !== "") { const res = validateCompValue(comp); if (!res) { return; // 校验失败,退出执行 } } //相等校验 if (comp.sameValueAsCompValue) { if ( formData.value[comp.prop] !== formData.value[comp.sameValueAsCompValue] ) { message.warning(`${comp.label}字段配置的两次输入内容不同`); return; // 校验失败,退出执行 } } } } const copyFormState = JSON.parse(JSON.stringify(formData.value)); for (let comp of compList.value) { if (["checkBox", "dataBind"].includes(comp.type)) { if (Array.isArray(copyFormState[comp.prop])) { copyFormState[comp.prop] = copyFormState[comp.prop].join(","); copyFormState[comp.prop] = rearrangeOthers(copyFormState[comp.prop]); } } if (comp.type === "dateTime") { if (copyFormState[comp.prop]) { copyFormState[comp.prop] = dayjs(copyFormState[comp.prop]).format( "YYYY-MM-DD HH:mm" ); } } } const res = await validateTryUpdateOrder( props.workConfCode, props.formWebUuid ); if (res === "covered") { return; // 校验失败,退出执行 } const params = { workConfCode: props.workConfCode, parentOrderId: route.query.orderId, subFormWebUuid: props.formWebUuid, }; await SmartFormApi.subFormNewRecord(params, copyFormState) .then((result) => { if (result.data.code === 200) { message.success("已提交表单"); emit("updateFormStatus", "已完成"); } else { message.error(result.data.message); // 接口返回错误,需要重置状态 throw new Error(result.data.message); } }); } catch (err) { console.error(err); } finally { // 无论成功失败,最终都重置状态 btnLoading.value = false; isCommitted.value = false; } };
主要优化点说明:
1. 使用 try-finally 结构,确保在任何情况下(包括所有 return 点)都会执行状态重置
2. 将所有校验失败的情况通过 return 退出,最终都会走到 finally 块
3. 接口调用失败时通过 throw new Error 触发 catch 块,最终也会走到 finally 块
4. 成功提交后仍然会执行 finally 块重置状态,这符合业务逻辑

浙公网安备 33010602011771号