UseElDialog - 对话框
组件介绍
UseElDialog 是基于 Element Plus 的 ElDialog 二次封装的对话框组件,专注于为弹窗提供开箱即用的全屏切换、标准化滚动区域、智能事件管理能力,同时遵循中后台最佳实践配置默认值,完整兼容原生 ElDialog 核心属性与插槽,可直接替换原生 ElDialog 使用,大幅降低弹窗场景的重复开发成本。
核心能力
- 开箱即用的全屏切换能力
内置全屏切换功能(showFullScreenIcon),头部默认显示全屏图标,点击即可一键切换全屏 / 窗口模式,自动切换全屏 / 还原图标,全屏状态下自动适配内容区高度为 calc (100dvh - 154px),完美兼容移动端视口,无需手动处理全屏状态下的布局适配。
- 标准化的滚动区域处理
内置 el-scrollbar 组件包装内容区域,自动处理全屏与非全屏状态下的高度计算:非全屏时支持自定义 maxHeight,全屏时自动撑满可用高度,默认开启 noresize 性能优化(适用于弹窗尺寸固定场景),解决原生弹窗内容溢出时的滚动条样式不一致问题,内容区自动处理 padding 保证滚动条不遮挡内容。
- 规范的布局与动态样式系统
标准化头部、内容区、底部三栏布局,支持通过 props 动态控制头部分割线(showHeaderBottomBorder)、底部分割线(showFooterTopBorder)、底部按钮对齐方式(footerPosition 支持 left/center/right),使用 CSS 变量实现样式动态切换,无需 scoped 样式穿透即可灵活定制外观,同时统一处理弹窗 padding 负值问题,保证布局一致性。
- 智能的关闭事件管理
创新的关闭事件处理机制:支持 strictCloseEvent 严格模式区分关闭来源,右上角关闭按钮默认智能复用 onCancel 事件逻辑,也可通过 onClose 自定义关闭事件;自动区分底部按钮手动点击与关闭按钮触发场景,避免事件重复执行,解决原生弹窗关闭事件逻辑混乱问题。
- 内置防抖按钮能力
底部默认按钮自动集成 UseElButton 组件,开箱即带防抖能力,无需额外配置即可避免重复提交问题;默认提供 "保存"、"取消" 两个标准按钮,支持自定义按钮文本(confirmBtnText/cancelBtnText)、取消按钮类型(cancelBtnType),也可通过 footer 插槽完全自定义底部内容。
- 中后台最佳实践默认配置
遵循企业级中后台弹窗使用规范,默认开启最佳实践配置:appendToBody=true 解决嵌套弹窗层级问题、destroyOnClose=true 关闭时自动销毁子元素避免内存泄漏、closeOnClickModal=false 防止点击遮罩误触关闭,无需业务侧重复配置,统一项目内弹窗交互规范。
- 完整的原生兼容与扩展能力
基于 ElDialog 封装,完整保留 v-model 控制显隐等核心能力,header、default、footer 插槽完全透传,支持自定义头部、内容区、底部内容;通过 defineExpose 暴露内部 el-dialog 实例(edRef)和 handleClose 方法,可直接调用原生弹窗所有能力,无迁移成本,同时补充原生弹窗缺失的全屏、智能事件等能力。
- 精细化的交互体验优化
内置多处体验优化:全屏图标 hover 透明度与颜色过渡、关闭按钮 hover 主题色效果、内容区滚动条样式适配、头部底部边框统一处理、关闭按钮位置微调,解决原生 ElDialog 在不同场景下的样式痛点,提供一致的交互体验。
- 灵活的功能开关配置
所有扩展功能均支持通过 props 独立开关:可关闭全屏图标、隐藏头部底部分割线、隐藏底部区域、关闭底部顶部分割线,支持自定义标题、最大高度、是否点击遮罩关闭、关闭时是否销毁等所有原生配置,满足新增、编辑、详情、确认等不同业务场景的弹窗需求。
- 安全的生命周期与性能优化
使用 computed 缓存弹窗实例方法,watch 立即执行初始化 CSS 变量保证样式首次渲染正确,scrollbar 默认开启 noresize 减少性能消耗,组件卸载时自动随 Vue 生命周期清理事件监听与 watcher,无内存泄漏问题,保证在动态渲染、频繁开关弹窗场景下的稳定性。
使用
Props
/**
* 组件props
*/
export default {
/**
* el-dialog的标题
*/
title: {
type: String,
default: ''
},
/**
* el-dialog自身是否插入至body元素上。嵌套的el-dialog必须指定该属性并赋值为 true 默认是
*/
appendToBody: {
type: Boolean,
default: true
},
/**
* el-dialog CSS 中的 margin-top 值 默认12dvh
*/
top: {
type: String,
default: '12dvh'
},
/**
* el-dialog内容区域最大高度 默认为autoMax,内部自动根据浏览器高度进行计算最大高度
*/
maxHeight: {
type: [String, Number],
default: 'autoCalcMaxHeight'
},
/**
* el-scrollbar不响应容器尺寸变化,如果容器尺寸不会发生变化,最好设置它可以优化性能
*/
noresize: {
type: Boolean,
default: true
},
/**
* 是否可以通过点击modal关闭el-dialog 默认否
*/
closeOnClickModal: {
type: Boolean,
default: false
},
/**
* 控制是否在关闭el-dialog后将子元素全部销毁 默认是
*/
destroyOnClose: {
type: Boolean,
default: true
},
/**
* 是否显示全屏图标 默认是
*/
showFullScreenIcon: {
type: Boolean,
default: true
},
/**
* 是否显示header底部border 默认是
*/
showHeaderBottomBorder: {
type: Boolean,
default: true
},
/**
* 是否显示footer 默认显示,可通过<template #footer></template>插槽自定义footer内容
*/
showFooter: {
type: Boolean,
default: true
},
/**
* 是否显示footer顶部border 默认否
*/
showFooterTopBorder: {
type: Boolean,
default: false
},
/**
* 底部定位 默认left
*/
footerPosition: {
type: String,
default: 'left',
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: '取消'
},
/**
* 确定按钮loading状态
*/
confirmLoading: {
type: Boolean,
default: false
},
/**
* 取消按钮类型
*/
cancelBtnType: {
type: String,
default: '',
validator: (val: string) =>
[
'',
'default',
'primary',
'success',
'warning',
'danger',
'info'
].includes(val)
},
/**
* 确定按钮事件
*/
onConfirm: {
type: Function,
default: () => {}
},
/**
* 取消按钮事件
*/
onCancel: {
type: Function,
default: () => {}
}
}Types
import type { ExtractPropTypes } from 'vue'
import componentProps from './props'
/**
* props类型
*/
export type Props = ExtractPropTypes<typeof componentProps>Expose
defineExpose({ edRef, handleClose })