Skip to content

UseElDrawer - 抽屉

组件介绍

UseElDrawer 是基于 Element Plus 的el-drawer进行二次封装的通用抽屉组件,旨在标准化抽屉的使用规范、统一交互逻辑、降低重复开发成本。该组件完整继承el-drawer核心能力,同时扩展了 footer 自定义、关闭事件精细化控制、样式全局统一等增强能力,仅需通过配置项即可完成绝大部分抽屉场景的开发,无需重复编写模板代码,大幅提升中后台系统中抽屉组件的开发效率和可维护性。

核心亮点

  1. 精细化的关闭事件控制:支持 strictCloseEvent 配置项区分抽屉右上角关闭图标事件(onClose)和取消逻辑(onCancel),可按需精准绑定事件逻辑,既保留原生关闭能力,又满足业务侧自定义关闭行为的需求。
  2. 灵活的 Footer 定制能力:通过 showFooter 配置项支持「默认显示确认 / 取消按钮」「隐藏 Footer」「自定义 Footer 内容」三种模式,无需手动编写 Footer 模板结构,适配不同业务场景的底部操作区需求。
  3. 全局统一的样式与布局:内置统一的抽屉 body、footer 样式规范,通过 footerPosition 配置项(left/center/right)一键控制 Footer 对齐方式,结合 CSS 变量实现样式全局统一,避免不同页面样式不一致问题。
  4. 原生能力增强兼容:完整继承 el-drawer 的 appendToBody、destroyOnClose、closeOnClickModal 等核心属性,并设置符合中后台场景的默认值(如 appendToBody 默认 true、closeOnClickModal 默认 false),无需重复配置基础属性。
  5. 手动操作与自动关闭隔离:内置 isManualOperate 标识区分「手动点击按钮关闭」和「自动触发关闭」场景,避免按钮点击与原生关闭逻辑冲突,保证关闭事件执行的准确性。

解决痛点

  1. 原生 el-drawer 关闭事件逻辑混乱
  • 痛点:原生 el-drawer 仅提供统一的关闭事件,无法区分「点击右上角关闭图标」「点击取消按钮」「点击遮罩层」等不同关闭场景,业务侧需手动编写大量判断逻辑,易出现事件执行错误、逻辑冗余问题。
  • 解决方案:组件封装 handleClosed 统一处理关闭逻辑,通过 strictCloseEvent 配置项可精准控制:开启后仅执行 onClose 事件,未开启且未自定义 onClose 时默认执行 onCancel,同时通过 isManualOperate 隔离手动按钮点击的关闭行为,关闭逻辑清晰且无需重复编写判断代码。

2.抽屉 Footer 开发重复且不统一

  • 痛点:每个抽屉页面需手动编写 Footer 模板(确认 / 取消按钮、布局、样式),不同页面的按钮文本、类型、对齐方式不一致,自定义 Footer 时还需重复处理插槽和样式,开发效率低且维护成本高。
  • 解决方案:组件内置 Footer 模板结构,通过 confirmBtnText、cancelBtnText、cancelBtnType 配置按钮文本和类型,footerPosition 控制对齐方式,showFooter 支持自定义插槽模式,减少 80% 以上的 Footer 重复模板代码,且样式和布局全局统一。
  1. 嵌套抽屉挂载异常
  • 痛点:原生 el-drawer 嵌套使用时若未手动设置 appendToBody 为 true,会出现层级错乱、遮罩层穿透等问题,每个嵌套抽屉需手动配置该属性,易遗漏且排查困难。
  • 解决方案:组件将 appendToBody 默认值设为 true,天然支持嵌套抽屉场景,无需手动配置,从底层避免嵌套挂载异常问题,适配中后台多层级抽屉的业务需求。
  1. 关闭后子元素销毁逻辑不统一
  • 痛点:原生 el-drawer 默认不销毁关闭后的子元素,导致再次打开抽屉时保留旧数据 / 状态,业务侧需手动处理销毁逻辑,不同页面实现方式不同,易出现数据残留、内存泄漏问题。
  • 解决方案:组件将 destroyOnClose 默认值设为 true,关闭抽屉后自动销毁所有子元素,保证每次打开抽屉都是全新状态,无需手动编写销毁逻辑,状态管理统一且无数据残留。
  1. 抽屉样式碎片化,维护成本高
  • 痛点:原生 el-drawer 需手动编写 body、footer 样式,不同页面的内边距、对齐方式、滚动区域样式不一致,后期调整样式需逐个页面修改,维护成本高且用户体验差。
  • 解决方案:组件内置 wyfe-ivue__drawer-body、wyfe-ivue__drawer-footer 统一样式类,通过 CSS 变量标准化内边距、滚动区域样式,footerPosition 配置项一键控制对齐方式,样式全局统一且可通过配置快速调整,无需逐个页面修改。
  1. 遮罩层关闭行为易误触
  • 痛点:原生 el-drawer 默认允许点击遮罩层关闭,中后台场景下用户易误触遮罩层导致抽屉关闭,需手动为每个抽屉设置 closeOnClickModal 为 false,重复配置且易遗漏。
  • 解决方案:组件将 closeOnClickModal 默认值设为 false,默认禁用遮罩层关闭行为,符合中后台「需明确操作才能关闭」的业务逻辑,无需重复配置该属性,降低误触风险。

使用案例

Types

js
import type { ExtractPropTypes } from 'vue'
import componentProps from './props'

/**
 * props类型
 */
export type Props = ExtractPropTypes<typeof componentProps>

ComponentProps

js
/**
 * 组件props
 */
export default {
  /**
   * el-drawer的标题
   */
  title: {
    type: String,
    default: '欢迎使用wyfe-ivue抽屉组件'
  },
  /**
   * 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
  },
  /**
   * 是否显示footer 默认显示,为CUSTOM可自定义footer
   */
  showFooter: {
    type: [Boolean, String],
    default: true,
    validator: (val: boolean | string) => [true, false, 'CUSTOM'].includes(val)
  },
  /**
   * 底部定位 默认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: '取消'
  },
  /**
   * 取消按钮类型 同ElButton类型
   */
  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 许可发布