弹窗与抽屉组件
目录
简介
本文档全面介绍基于 Vue 3 组合式 API 的弹窗(Dialog)与抽屉(Drawer)组件体系。重点阐述 BaseDialog 与 BaseDrawer 作为基础组件的设计模式,以及业务级对话框(如 ArtificialStationDialog、ProcessRouterDialog)如何通过继承与扩展实现可复用模板。文档涵盖通信协议、动画机制、遮罩层管理、键盘事件处理及微前端环境下的跨应用通信方案。
项目结构
图示来源
src/components/BaseDialog/BaseDialog.tsxsrc/components/BaseDrawer/BaseDrawer.tsxsrc/components/ArtificialStationDialog/ArtificialStationDialog.tsxsrc/components/ProcessRouterDialog/ProcessRouterDialog.tsxsrc/hooks/Dialog.tssrc/hooks/drawer.ts
本节来源
src/components/BaseDialog/BaseDialog.tsxsrc/components/BaseDrawer/BaseDrawer.tsxsrc/components/ArtificialStationDialogsrc/components/ProcessRouterDialog
核心组件
BaseDialog 和 BaseDrawer 是整个弹窗系统的核心基础组件,采用 Vue 3 的组合式 API 实现,通过 props 和 emits 定义标准化的通信协议。
BaseDialog 封装了 el-dialog 组件,提供统一的标题栏、关闭按钮、确认/取消按钮布局,并通过 v-slots 支持灵活的内容与页脚定制。其 SCSS 样式文件定义了阴影、圆角、内边距等视觉规范。
BaseDrawer 基于 el-drawer 构建,主要用于侧边栏交互。其 SCSS 模块通过 @keyframes 定义了背景图标的动画效果(iconFrames),实现了视觉上的动态提示。组件通过 clickable 属性控制遮罩层是否可点击关闭。
本节来源
src/components/BaseDialog/BaseDialog.tsxsrc/components/BaseDialog/BaseDialog.scsssrc/components/BaseDrawer/BaseDrawer.tsxsrc/components/BaseDrawer/BaseDrawer.module.scss
架构概述
图示来源
src/components/BaseDialog/BaseDialog.tsxsrc/components/ArtificialStationDialog/hook.tssrc/components/ProcessRouterDialog/hook.ts
详细组件分析
基础弹窗组件分析
组件通信协议
BaseDialog 通过 props 接收配置(如 title, width, height),并通过 emits 定义事件接口(close, confirm, open)。业务组件通过 v-model 绑定 visible 状态,实现双向数据绑定。
图示来源
src/components/BaseDialog/BaseDialog.tsxsrc/components/ArtificialStationDialog/ArtificialStationDialog.tsx
业务级对话框分析
ArtificialStationDialog 实现模式
ArtificialStationDialog 继承 BaseDialog,并引入 useSelectDialog 钩子。该钩子封装了数据获取(getUserList)、状态管理(dataSource, selections)、表单验证和提交逻辑(onEditConfirm)。通过 hook.ts 文件,实现了业务逻辑与 UI 的分离,形成可复用的模板。
图示来源
src/components/ArtificialStationDialog/ArtificialStationDialog.tsxsrc/components/ArtificialStationDialog/hook.tssrc/components/ArtificialStationDialog/api.ts
ProcessRouterDialog 实现模式
ProcessRouterDialog 同样使用 useSelectDialog 钩子,但其业务逻辑聚焦于工艺路线选择。onOpen 时根据 productId 获取关联的工艺路线,再根据路线 ID 过滤出可选的工位列表。onConfirm 时将选中的工位数据通过 emit 传递给父组件。
本节来源
src/components/ArtificialStationDialog/ArtificialStationDialog.tsxsrc/components/ArtificialStationDialog/hook.tssrc/components/ProcessRouterDialog/ProcessRouterDialog.tsxsrc/components/ProcessRouterDialog/hook.ts
交互细节分析
遮罩层与层级管理
基础组件依赖 element-plus 的 el-dialog 和 el-drawer,其遮罩层(.v-modal)的 z-index 由框架管理。业务组件通过 appendToBody 属性确保弹窗挂载到 body 下,避免被父级 overflow 影响。多层级堆叠通过 z-index 层级控制,后打开的弹窗具有更高的 z-index。
键盘事件监听
BaseDialog 和 BaseDrawer 均支持 ESC 键关闭功能,这是 element-plus 组件的内置行为。show-close={false} 隐藏了默认关闭按钮,但 ESC 功能依然有效。
本节来源
src/components/BaseDialog/BaseDialog.tsxsrc/components/BaseDrawer/BaseDrawer.tsxnode_modules/element-plus/theme-chalk/src/common/popup.scss
依赖分析
图示来源
src/components/BaseDialog/BaseDialog.tsxsrc/components/BaseDrawer/BaseDrawer.tsxsrc/components/ArtificialStationDialog/ArtificialStationDialog.tsxsrc/components/ProcessRouterDialog/ProcessRouterDialog.tsxsrc/components/*/hook.ts
性能考虑
- 按需加载:使用
destroy-on-close属性确保弹窗关闭后销毁内部组件,释放内存。 - 防抖处理:在
onRemoteMethod等涉及网络请求的方法中,应添加防抖逻辑,避免频繁请求。 - 大数据量:对于包含表格的弹窗,应启用分页或虚拟滚动,避免一次性渲染大量 DOM 节点。
故障排除指南
- 弹窗无法打开:检查
v-model绑定的visible值是否正确响应,确认onShowDialog等触发方法是否被调用。 - 数据未更新:确保在
onConfirm回调中正确调用了ctx.emit('confirm', data),并检查父组件是否监听了该事件。 - 样式错乱:检查 SCSS 模块的类名是否正确导入和使用,避免全局样式污染。
- 微前端通信失败:确认跨应用事件总线(如
EventBus或CustomEvent)已正确初始化和监听。
本节来源
src/hooks/Dialog.tssrc/components/ArtificialStationDialog/hook.tssrc/components/ProcessRouterDialog/hook.ts
结论
BaseDialog 和 BaseDrawer 统一弹窗、抽屉的交互方式。组件通过 Vue 3 组合式 API 和 useVModel 传递 props 与 emits,将业务逻辑封装在独立的 hook.ts 中,并结合 element-plus 处理遮罩层和键盘事件。