UseElDrawer - 抽屉
组件介绍
UseElDrawer 是基于 Element Plus 的 ElDrawer 二次封装的抽屉组件,专注于为抽屉提供开箱即用的全屏切换、标准化底部操作栏能力,同时优化关闭事件逻辑与业务向默认配置,完整兼容原生 ElDrawer 核心属性,可直接替换原生 ElDrawer 使用,大幅降低中后台场景下抽屉表单、详情页等场景的重复开发成本。
核心能力
- 开箱即用的全屏切换能力
内置全屏切换图标,点击即可一键切换抽屉全屏 / 原尺寸状态,自动适配尺寸为 100%,图标随状态自动切换(全屏 / 退出全屏对应不同图标),无需手动编写全屏控制逻辑,满足大屏编辑、详情全览等场景的全屏查看需求,将 showFullScreenIcon 设置为 false 即可隐藏全屏入口。
- 标准化的底部操作栏
默认内置标准化底部操作栏,开箱提供 “保存”“取消” 两个常用操作按钮,支持自定义确定 / 取消按钮文本、取消按钮类型;底部按钮对齐方式可配置,同时支持 footer 插槽完全自定义底部内容,满足不同业务的底部操作需求。
- 灵活的关闭事件管理
支持灵活的关闭事件控制:可通过 strictCloseEvent 开启严格关闭模式,自定义右上角关闭图标事件(onClose);未自定义关闭事件时,右上角关闭默认复用取消按钮逻辑;手动触发确定 / 取消按钮时自动标记操作状态,避免抽屉关闭后重复触发关闭回调;同时对外暴露 handleClose 方法,支持外部主动控制抽屉关闭,兼顾不同关闭场景的逻辑定制需求。
- 原生抽屉完全兼容
基于 ElDrawer 封装,完整保留 appendToBody、destroyOnClose、closeOnClickModal 等原生核心属性,header、default、footer 插槽完全透传,可直接替换原生 ElDrawer 使用,无迁移成本;同时针对业务场景优化默认配置,补充原生抽屉缺失的全屏切换、标准化底部栏能力,覆盖绝大多数中后台抽屉使用场景。
- 内置内容滚动优化
抽屉内容区域内置 el-scrollbar 滚动容器,自动处理滚动条占位导致的内容 padding 不一致问题,为滚动视图补充右侧内边距,避免内容过长时滚动条遮挡文字或元素,解决原生抽屉长内容滚动时的样式错位问题,保证长表单、长详情场景下的浏览体验一致性。
- 样式与嵌套场景兼容
默认开启 appendToBody,天然支持抽屉嵌套场景,避免多层抽屉层级错误;因默认挂载到 body 下,采用全局类名 + CSS 变量的样式方案替代 scoped 样式,保证样式生效的同时避免全局污染;统一头部、内容区、底部的内边距规范,修复原生抽屉内容区 padding 不一致问题,保证组件在不同布局场景下的样式统一。
- 业务向默认配置优化
针对中后台常用场景优化默认配置:默认尺寸 1100px(适配表单、详情页的常规宽度)、默认关闭点击遮罩关闭(closeOnClickModal 默认 false,避免误操作丢失编辑内容)、默认关闭后销毁子元素(destroyOnClose 默认 true,避免表单状态残留)、默认按钮文本为 “保存”/“取消”,开箱即用无需重复配置高频属性,减少业务重复代码。
- 完善的实例暴露与状态管理
组件对外暴露原生抽屉实例(edRef)和主动关闭方法(handleClose),支持外部调用原生 ElDrawer 的所有方法或主动控制抽屉关闭;默认开启 destroyOnClose,抽屉关闭时自动销毁内部子组件,清除事件相关状态,避免内存泄漏和组件状态残留,保证动态渲染、频繁开关场景下的组件稳定性。
使用
Props
/**
* 组件props
*/
export default {
/**
* el-drawer的标题
*/
title: {
type: String,
default: ''
},
/**
* el-drawer的窗体的大小, 当使用number类型时, 以像素为单位, 当使用string类型时, 请传入'xx%'、'xxxpx'等,否则便会以number类型解释 默认1100px
*/
size: {
type: [Number, String],
default: 1100
},
/**
* el-drawer自身是否插入至body元素上。嵌套的el-drawer必须指定该属性并赋值为 true 默认是
*/
appendToBody: {
type: Boolean,
default: true
},
/**
* 控制是否在关闭el-drawer后将子元素全部销毁 默认是
*/
destroyOnClose: {
type: Boolean,
default: true
},
/**
* 是否可以通过点击modal关闭el-drawer 默认否
*/
closeOnClickModal: {
type: Boolean,
default: false
},
/**
* 是否显示全屏图标 默认是
*/
showFullScreenIcon: {
type: Boolean,
default: true
},
/**
* 是否显示footer 默认显示,可通过<template #footer></template>插槽自定义footer内容
*/
showFooter: {
type: Boolean,
default: true
},
/**
* 底部定位 默认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
},
/**
* 取消按钮类型 同ElButton类型
*/
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 })