ETest-Vue-FastAPI/对话框点击外部关闭问题修复说明.md

5.7 KiB
Raw Permalink Blame History

对话框点击外部关闭问题修复说明

问题描述

系统中所有的对话框el-dialog都存在一个问题当用户点击对话框外部的遮罩层区域时对话框会自动关闭。这会导致用户在填写表单时如果不小心点击了对话框外部所有填写的内容都会丢失。

问题原因

Element UI 的 el-dialog 组件有一个属性 close-on-click-modal,其默认值为 true。这意味着默认情况下,点击遮罩层(对话框外部区域)会触发对话框关闭。

解决方案

方案1全局配置推荐但可能需要重启

src/main.js 文件中,添加全局配置来覆盖 Element UI Dialog 组件的默认行为:

// 全局设置 el-dialog 默认不允许点击遮罩层关闭
// 解决所有对话框点击外部区域会关闭的问题
// 必须在 Vue.use(Element) 之后执行
const DialogConstructor = Vue.component('ElDialog')
if (DialogConstructor && DialogConstructor.options && DialogConstructor.options.props) {
  const closeOnClickModalProp = DialogConstructor.options.props.closeOnClickModal
  if (closeOnClickModalProp) {
    closeOnClickModalProp.default = false
  }
}

注意:此方法需要完全重启前端服务(不是热重载),并清除浏览器缓存。

方案2逐个添加属性最可靠

在每个对话框标签上添加 :close-on-click-modal="false" 属性:

<!-- 修改前 -->
<el-dialog :title="title" :visible.sync="open" width="1200px" append-to-body>

<!-- 修改后 -->
<el-dialog :title="title" :visible.sync="open" width="1200px" append-to-body :close-on-click-modal="false">

方案3使用批量修复脚本

运行提供的 fix_dialogs.js 脚本来批量修改所有对话框:

node fix_dialogs.js

实施步骤

步骤1修改main.js已完成

文件:ruoyi-fastapi-frontend/src/main.js

步骤2修改主要对话框已完成

已修改的文件:

  • ruoyi-fastapi-frontend/src/views/warehouse/receipt/index.vue - 入库单对话框
  • ruoyi-fastapi-frontend/src/views/warehouse/sample/index.vue - 样品对话框

步骤3重启前端服务

重要:必须完全停止并重新启动前端服务,热重载可能不会生效。

# 停止当前服务 (Ctrl+C)
# 然后重新启动
npm run dev

步骤4清除浏览器缓存

  1. 打开浏览器开发者工具F12
  2. 右键点击刷新按钮
  3. 选择"清空缓存并硬性重新加载"

或者使用快捷键:

  • Chrome/Edge: Ctrl + Shift + Delete
  • Firefox: Ctrl + Shift + Delete

步骤5批量修改其他对话框可选

如果全局配置不生效,运行批量修复脚本:

node fix_dialogs.js

这将自动为所有对话框添加 :close-on-click-modal="false" 属性。

影响范围

此修改会影响整个项目中所有使用 el-dialog 的对话框,包括但不限于:

  • 入库单管理对话框(已手动修改)
  • 样品管理对话框(已手动修改)
  • 用户管理对话框
  • 角色管理对话框
  • 菜单管理对话框
  • 测试工单对话框
  • 测试流程对话框
  • 等等...共20+个对话框)

验证方法

修改后,请测试以下场景:

  1. 打开任意对话框,点击对话框外部区域,对话框不应关闭
  2. 点击对话框右上角的关闭按钮X对话框应正常关闭
  3. 点击对话框底部的"取消"按钮,对话框应正常关闭
  4. 点击对话框底部的"确定"按钮,对话框应正常关闭并提交数据
  5. 按 ESC 键,对话框应正常关闭(如果需要禁用此功能,可设置 :close-on-press-escape="false"

故障排查

问题:修改后对话框仍然可以点击外部关闭

可能原因1:前端服务没有完全重启

  • 解决方法完全停止服务Ctrl+C然后重新运行 npm run dev

可能原因2:浏览器缓存

  • 解决方法清除浏览器缓存并硬性重新加载Ctrl+Shift+R

可能原因3:全局配置未生效

  • 解决方法使用方案2或方案3直接在对话框标签上添加属性

可能原因4:某些对话框使用了显式的 :close-on-click-modal="true"

  • 解决方法:搜索并修改这些特殊情况

问题:如何验证全局配置是否生效

在浏览器控制台中运行:

// 检查Dialog组件的默认props
const DialogConstructor = Vue.component('ElDialog')
console.log(DialogConstructor.options.props.closeOnClickModal.default)
// 应该输出: false

备用方案

如果以上方法都不生效,可以使用以下临时方案:

方案A使用CSS禁用遮罩层点击

src/assets/styles/index.scss 中添加:

// 禁用对话框遮罩层的点击事件
.el-dialog__wrapper {
  pointer-events: none;
  
  .el-dialog {
    pointer-events: auto;
  }
}

方案B使用全局事件监听

src/main.js 中添加:

// 全局拦截对话框关闭事件
Vue.prototype.$msgbox = function(options) {
  return MessageBox({
    ...options,
    closeOnClickModal: false
  })
}

日期

  • 初次修复2025-12-05
  • 更新方案2025-12-05

相关问题

  • 入库单详情查看错误(已同时修复)
  • 数据模型字段缺失问题(已同时修复)

附加工具

批量修复脚本使用说明

fix_dialogs.js 脚本会:

  1. 扫描 src/viewssrc/components 目录下的所有 .vue 文件
  2. 查找所有 <el-dialog> 标签
  3. 为没有 close-on-click-modal 属性的对话框自动添加 :close-on-click-modal="false"
  4. 输出修改的文件列表

运行前请确保:

  • 已安装 Node.js
  • 在项目根目录下运行
  • 建议先备份代码或使用Git版本控制