Skip to content

UseElDialog - 对话框

组件介绍

UseElDialog 是基于 Element Plus 的el-dialog组件进行二次封装的通用对话框组件,旨在解决原生el-dialog在中后台项目开发中存在的配置繁琐、样式不统一、事件逻辑混乱、扩展成本高等问题。该组件通过封装通用配置、统一样式规范、优化事件处理逻辑、预留灵活扩展入口,大幅提升对话框开发效率,同时保证组件的通用性与可定制性,适配中后台系统各类弹窗交互场景。

核心亮点

  1. 配置化驱动,减少重复编码:将 el-dialog 高频配置(如标题、是否点击遮罩关闭、销毁策略等)封装为标准化 props,无需在每个弹窗页面重复编写 el-dialog 基础属性,仅需通过 props 传入差异化配置即可快速生成对话框。
  2. 样式统一且支持个性化定制:内置统一的头部、主体、底部样式规范,同时通过 CSS 变量 + 样式配置项(headerStyleConfig、footerPosition)支持个性化调整,兼顾系统风格一致性与业务定制需求。
  3. 事件逻辑精细化管控:区分手动操作(确认 / 取消按钮)与自动关闭(右上角关闭、遮罩点击)场景,优化 close/cancel 事件触发逻辑,支持严格区分 close 事件,避免原生组件事件触发混乱的问题。
  4. 灵活的布局与扩展能力:内置滚动容器、自定义头部 / 底部插槽、footer 自定义模式(默认 / 自定义),适配不同内容展示、操作按钮布局的需求,无需破坏组件结构即可扩展功能。
  5. 性能优化细节:默认开启 destroyOnClose 减少内存占用,el-scrollbar 支持 noresize 配置优化渲染性能,appendToBody 规避嵌套弹窗层级问题。

解决痛点

  1. 原生 el-dialog 样式定制繁琐且不统一
  • 痛点:原生 el-dialog 的头部、底部样式需手动编写自定义样式覆盖,不同页面的弹窗表头背景、文字颜色、底部对齐方式等样式不统一,且嵌套弹窗样式易受父容器影响,样式调试成本高。
  • 解决方案:组件内置统一的头部 / 底部样式(如表头边框、内边距、关闭按钮位置),通过 CSS 变量(--wyfe-ivue__dialog-header-bg 等)和 props(headerStyleConfig、footerPosition)集中管理样式属性,仅需配置即可调整样式,同时默认开启 appendToBody 规避嵌套样式污染问题,保证样式一致性。
  1. 原生 el-dialog 事件逻辑混乱,关闭行为不可控
  • 痛点:原生 el-dialog 的 closed 事件无法区分 “点击取消按钮”“点击右上角关闭”“点击遮罩关闭” 等场景,不同关闭行为需手动判断来源,且 close/cancel 事件易混淆,导致关闭逻辑处理混乱,不同开发者实现方式不一致。
  • 解决方案:组件封装 handleClosed 统一处理关闭逻辑,通过 isManualOperate 区分手动操作(确认 / 取消按钮)与自动关闭,结合 strictCloseEvent 配置项可严格区分 onClose(右上角关闭)与 onCancel(取消按钮 / 默认关闭)事件,确保不同关闭场景的逻辑可精准管控,无需重复编写事件判断代码。
  1. 弹窗内容滚动、布局需重复封装
  • 痛点:每个弹窗需手动封装 el-scrollbar 处理内容滚动,且需调整滚动容器样式适配 dialog 内边距,底部按钮区域(footer)的对齐方式、边框样式需重复编写,开发效率低。
  • 解决方案:组件内置 el-scrollbar 作为内容容器,支持 maxHeight、noresize 配置优化滚动体验,同时封装 footer 区域的默认样式(边框、内边距)和对齐方式配置,默认提供确认 / 取消按钮,也支持 CUSTOM 模式自定义 footer 内容,减少 80% 以上的布局重复代码。
  1. 原生 el-dialog 高频配置重复编写
  • 痛点:中后台项目中每个弹窗需重复配置 appendToBody、closeOnClickModal、destroyOnClose 等属性,且默认值不统一(如部分弹窗忘记开启 destroyOnClose 导致内存泄漏),配置遗漏易引发线上问题。
  • 解决方案:组件将高频配置封装为 props 并设置合理默认值(如默认 appendToBody: true、destroyOnClose: true、closeOnClickModal: false),无需每个页面重复配置,同时通过 props 校验(如 footerPosition 仅支持 left/center/right)避免配置错误,降低开发失误率。
  1. 扩展自定义内容时易破坏组件原有逻辑
  • 痛点:原生 el-dialog 自定义头部、底部内容时,需替换默认的 header/footer 插槽,易导致原有样式、事件逻辑失效(如自定义 header 后关闭按钮样式丢失),且自定义按钮需手动处理关闭逻辑,与原有关闭行为冲突。
  • 解决方案:组件预留 header、footer 插槽(showHeader 控制是否显示默认头部,showFooter 支持 CUSTOM 模式自定义底部),自定义内容时不会覆盖原有样式和事件逻辑;同时封装 handleClick 方法统一处理按钮点击逻辑,确保自定义按钮的关闭行为与组件原有逻辑一致,扩展功能时无需担心冲突。

使用案例

ComponentProps

js
import type { PropType } from 'vue'

/**
 * 组件props
 */
export default {
  /**
   * el-dialog的标题
   */
  title: {
    type: String,
    default: '欢迎使用wyfe-ivue对话框组件'
  },
  /**
   * el-dialog自身是否插入至body元素上。嵌套的el-dialog必须指定该属性并赋值为 true 默认是
   */
  appendToBody: {
    type: Boolean,
    default: true
  },
  /**
   * el-dialog头部区域样式配置
   */
  headerStyleConfig: {
    type: Object as PropType<Record<string, any>>,
    default: () => ({ bgColor: 'var(--theme-color)', color: '#fff' })
  },
  /**
   * el-dialog内容区域最大高度
   */
  maxHeight: {
    type: [String, Number],
    default: ''
  },
  /**
   * el-scrollbar不响应容器尺寸变化,如果容器尺寸不会发生变化,最好设置它可以优化性能
   */
  noresize: {
    type: Boolean,
    default: true
  },
  /**
   * 是否可以通过点击modal关闭el-dialog 默认否
   */
  closeOnClickModal: {
    type: Boolean,
    default: false
  },
  /**
   * 控制是否在关闭el-dialog后将子元素全部销毁 默认是
   */
  destroyOnClose: {
    type: Boolean,
    default: true
  },
  /**
   * 是否显示header 默认显示
   */
  showHeader: {
    type: Boolean,
    default: true
  },
  /**
   * 是否显示footer 默认显示,为CUSTOM可自定义footer
   */
  showFooter: {
    type: [Boolean, String],
    default: true,
    validator: (val: boolean | string) => [true, false, 'CUSTOM'].includes(val)
  },
  /**
   * 底部定位 默认right
   */
  footerPosition: {
    type: String,
    default: 'right',
    validator: (val: string) => ['left', 'center', 'right'].includes(val)
  },
  /**
   * 是否严格区分close事件 默认否 和onClose事件二选一设置一个即可
   */
  strictCloseEvent: {
    type: Boolean,
    default: false
  },
  /**
   * 抽屉关闭图标事件 若未设置且未开启strictCloseEvent则默认执行onCancel事件
   */
  onClose: {
    type: Function,
    default: () => {}
  },
  /**
   * 确定按钮文本
   */
  confirmBtnText: {
    type: String,
    default: '保存'
  },
  /**
   * 取消按钮文本
   */
  cancelBtnText: {
    type: String,
    default: '取消'
  },
  /**
   * 取消按钮类型
   */
  cancelBtnType: {
    type: String,
    default: '',
    validator: (val: string) =>
      [
        '',
        'default',
        'primary',
        'success',
        'warning',
        'danger',
        'info'
      ].includes(val)
  },
  /**
   * 确定按钮事件
   */
  onConfirm: {
    type: Function,
    default: () => {}
  },
  /**
   * 取消按钮事件
   */
  onCancel: {
    type: Function,
    default: () => {}
  }
}

Props && Expose

js
const props = defineProps(componentProps)

defineExpose({ edRef, handleClose })

基于 MIT 许可发布