当前位置: 首页 > article >正文

bug 记录 - 使用 el-dialog 的 before-close 的坑

需求说明

  • 弹窗中内嵌一个 form 表单
    在这里插入图片描述
  • 原始代码
<script setup lang="ts">
import { reactive, ref } from "vue"
import type { FormRules } from 'element-plus'
const ruleFormRef = ref()
interface RuleForm {name: stringregion: number | null
}
const ruleForm = reactive<RuleForm>({name: '',region: null,
})
const rules = reactive<FormRules<RuleForm>>({name: [{ required: true, message: '请填写姓名', trigger: 'blur' },],region: [{ required: true, message: '请选择区域编码', trigger: 'change' },]
})
const dialogVisible = ref(false);
function handelDialogPop(type: string) {if (type == "open") {dialogVisible.value = true; // 开启弹窗} else if (type == "submit") {ruleFormRef.value.validate((valid: any, fields: any) => {if (valid) {console.log('提交成功')// 关闭弹窗ruleFormRef.value.resetFields();dialogVisible.value = false;} else {console.log('error submit!', fields)}})} else if (type == "cancel") {// 关闭弹窗ruleFormRef.value.resetFields();dialogVisible.value = false}
}
</script>
<template><div class="dataBox"><el-button type="primary" @click="handelDialogPop('open')">开启弹窗</el-button><el-dialog v-model="dialogVisible" title="弹窗" width="500"><el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto"><el-form-item label="姓名" prop="name"><el-input v-model="ruleForm.name" /></el-form-item><el-form-item label="区域" prop="region"><el-select v-model="ruleForm.region" placeholder="区域编码"><el-option label="第一区" :value="1" /><el-option label="第二区" :value="2" /></el-select></el-form-item></el-form><template #footer><div class="dialog-footer"><el-button type="primary" plain @click="handelDialogPop('cancel')">取消</el-button><el-button type="primary" @click="handelDialogPop('submit')">提交</el-button></div></template></el-dialog></div>
</template>
  • 点击取消按钮,或者提交通过校验时,先执行了 form 表单的 resetFields 事件。此代码会将表单的值重置为初始值,并且移除所有校验。这样可以保证下次点开弹窗时,不会保留上次操作 form 的痕迹。
    在这里插入图片描述
  • 为了省事儿,我把所有对 dialog 的操作都写进了 handelDialogPop 函数里,传入 type 来区分是什么事件(这里就是出问题的关键

发现问题

  • 手动点击关闭按钮,或者点击 model 空白区域时,弹窗被关闭。未执行 form 表单的 resetFields 方法,所以再次打开时,弹窗保留了上次操作的痕迹(form 表单未重置)
    在这里插入图片描述

  • 因此需要监听 dialog 的关闭事件,官方提供了一个方法,before-close
    在这里插入图片描述

<el-dialog v-model="dialogVisible" title="弹窗" width="500" :before-close="handelDialogPop('cancel')">
...
  • 问题出现了,一进入页面时,直接抛错。报错信息可看出,before-close 被触发了

在这里插入图片描述

在这里插入图片描述

问题解决

  • 文档中表明,before-close 传参,done 说明会执行。
    在这里插入图片描述
  • 重新为 before-close 封装一个函数

在这里插入图片描述

完整代码

<script setup lang="ts">
import { reactive, ref } from "vue"
import type { FormRules } from 'element-plus'
const ruleFormRef = ref()
interface RuleForm {name: stringregion: number | null
}
const ruleForm = reactive<RuleForm>({name: '',region: null,
})
const rules = reactive<FormRules<RuleForm>>({name: [{ required: true, message: '请填写姓名', trigger: 'blur' },],region: [{ required: true, message: '请选择区域编码', trigger: 'change' },]
})
const dialogVisible = ref(false);
function beforeCloseDialog() {console.log("执行了 beforeCloseDialog");ruleFormRef.value.resetFields();dialogVisible.value = false
}
function handelDialogPop(type: string) {if (type == "open") {dialogVisible.value = true} else if (type == "submit") {ruleFormRef.value.validate((valid: any, fields: any) => {if (valid) {console.log('提交成功')beforeCloseDialog();} else {console.log('error submit!', fields)}})} else if (type == "cancel") {// 关闭弹窗beforeCloseDialog()}
}
</script>
<template><div class="dataBox"><el-button type="primary" @click="handelDialogPop('open')">开启弹窗</el-button><el-dialog v-model="dialogVisible" title="弹窗" width="500" :before-close="beforeCloseDialog"><el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto"><el-form-item label="姓名" prop="name"><el-input v-model="ruleForm.name" /></el-form-item><el-form-item label="区域" prop="region"><el-select v-model="ruleForm.region" placeholder="区域编码"><el-option label="第一区" :value="1" /><el-option label="第二区" :value="2" /></el-select></el-form-item></el-form><template #footer><div class="dialog-footer"><el-button type="primary" plain @click="handelDialogPop('cancel')">取消</el-button><el-button type="primary" @click="handelDialogPop('submit')">提交</el-button></div></template></el-dialog></div>
</template>
http://www.lryc.cn/news/2402285.html

相关文章:

  • Next.js 中间件鉴权绕过漏洞 CVE-2025-29927
  • 基于YOLO-NAS-Pose的无人机象群姿态估计:群体行为分析的突破
  • 8天Python从入门到精通【itheima】-71~72(数据容器“序列”+案例练习)
  • 中达瑞和SHIS高光谱相机在黑色水彩笔墨迹鉴定中的应用
  • dvwa10——XSS(DOM)
  • dvwa14——JavaScript
  • 外网访问内网服务器常用的三种简单操作步骤方法,本地搭建网址轻松让公网连接
  • 机器学习实验八--基于pca的人脸识别
  • UDP包大小与丢包率的关系:原理分析与优化实践
  • ubuntu 端口复用
  • Registry和docker有什么关系?
  • C++11实现TCP网络通讯服务端处理逻辑简化版
  • python3.9带 C++绑定的基础镜像
  • Elasticsearch中的语义搜索(Semantic Search)介绍
  • LabVIEW的AMC架构解析
  • MySQL 索引:为使用 B+树作为索引数据结构,而非 B树、哈希表或二叉树?
  • ubuntu屏幕复制
  • Flutter嵌入式开发实战 ——从树莓派到智能家居控制面板,打造工业级交互终端
  • Spring WebFlux 整合AI大模型实现流式输出
  • 验证电机理论与性能:电机试验平板提升测试效率
  • Vue.js应用结合Redis数据库:实践与优化
  • Simplicity studio SDK下载和安装,创建工程
  • OpenCV——Mac系统搭建OpenCV的Java环境
  • 更新Java的环境变量后VScode/cursor里面还是之前的环境变量
  • 【设计模式-3.4】结构型——代理模式
  • 电脑频繁黑屏怎么办
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Sound Board(音响控制面板)
  • 关于大数据的基础知识(一)——定义特征结构要素
  • chrome使用手机调试触屏web
  • 浅谈量子计算:从实验室突破到产业落地的中国实践