Skip to content

Drawer 抽屉

xy-drawer 更适合详情查看、大表单编辑和侧边说明这类“希望保留主页面上下文”的场景。当前实现延续了项目内的 placement 习惯,补齐了 direction、可拖拽尺寸、自定义头部 slot props、焦点事件和 handleClose() expose。

迁移提示

  • 后台项目里如果只是想收口抽屉的背景、边框、阴影或头体尾节奏,优先使用:
    • header-class / body-class / footer-class
    • 组件原生 class
    • 对应 --xy-drawer-* 变量
  • 不建议继续在页面层 deep 到 .xy-drawer__panel / __header / __body / __footer
  • 新代码优先使用:
    • header 插槽
    • 组件原生 class
  • title 插槽和 custom-class 只保留兼容语义,不应再作为新的默认写法。

基础用法

右侧抽屉适合做详情查看和表单编辑,能保留列表页的上下文。

基础用法侧边面板

抽屉用于从侧边滑出的面板,适合编辑表单、详情查看等场景。

方向与尺寸对照

placement 仍然是项目内推荐写法;如果你需要使用 direction,它会优先覆盖 placement

弹出位置Placement

抽屉支持从左、右、上、下四个方向弹出,适应不同场景。

受控显示与关闭策略

抽屉通常由列表页外部控制打开、关闭、方向和宽度,这样更适合做筛选面板和详情面板联动。

placement=rightsize=480px关闭后保留内容

自定义头部与 slot props

header 插槽会拿到 closetitleIdtitleClass,既能自定义头部,又不会丢掉可访问标题和关闭链路。

自定义头部Header Slot

通过 header slot 可以完全自定义抽屉头部区域。

可拖拽尺寸

打开 resizable 后,拖动抽屉边缘可以实时改宽高,并通过 resize-startresizeresize-end 拿到像素尺寸。

direction=rtl最近一次尺寸:未拖拽

全屏与关闭图标

fullscreen 会让抽屉直接占满视口,close-icon 则用于替换默认关闭图标,适合工作区式的大面板。

fullscreen=true

嵌套抽屉

默认 append-to-body 就是 true,所以内层抽屉会自动进入更高层级,不需要额外配置。

关闭控制与上下抽屉

directionbefore-closewith-headershow-close 适合做更接近配置面板或顶部筛选层的抽屉。

关闭拦截中

无遮罩可穿透

modal=false 时抽屉不会渲染遮罩;再配合 modal-penetrable,背景区域仍然可以继续交互。

使用说明

  • direction 优先级高于 placement;如果两者同时传入,会以 direction 推导出的方向为准。
  • append-to 优先级高于 append-to-body;一旦显式指定挂载目标,就会直接 teleport 到该节点。
  • close-on-click-modal 优先级高于 close-on-overlayclose-on-press-escape 优先级高于 close-on-esc,这两个别名提供了额外兼容。
  • modal-class 作用在遮罩层容器上,因此只在 modal=true 时生效;组件的原生 classstyle 会透传到抽屉面板本身。
  • modal=false 时不会响应外部点击关闭;如果还希望背景可点击,请再打开 modal-penetrable
  • 键盘焦点默认会被限制在抽屉内部;但在 modal=falsemodal-penetrable=true 的场景里,指针点击外部可交互元素时,不会被抽屉强制拉回焦点。
  • 抽屉内容默认是懒渲染的,也就是第一次真正打开后才会挂载内部内容;需要拿 DOM 或测量尺寸时,优先放到 open 之后处理。
  • destroy-on-close 适合每次打开都希望重新挂载内容的场景,例如重置复杂表单、重新执行初始化逻辑。
  • 关闭前拦截优先于销毁逻辑;如果 before-close 取消了关闭,内容不会被卸载。
  • title 插槽和 custom-class 仅保留兼容能力;新代码优先使用 header 插槽和组件原生 class

direction 与 placement 的区别

  • 继续保留项目内的 placement 写法,不强制切到 direction
  • 默认 size 仍然是 420,默认 append-to-body 仍然是 true,以保持当前项目里的既有使用习惯。
  • 保留了 title 插槽和 custom-class 的兼容层,但会给出废弃提示;新代码优先使用 header 插槽和组件原生 class

API

Drawer Attributes

属性说明类型默认值
model-value是否打开抽屉DrawerProps["modelValue"]false
title抽屉标题;当你完全自定义 header 时,仍建议传入用于可访问名称兜底string''
size抽屉宽度或高度;左右方向作用于宽度,上下方向作用于高度DrawerProps["size"]420
placement项目内保留的打开方向写法DrawerPlacement'right'
direction方向别名,优先级高于 placementDrawerDirectionundefined
append-to-body默认是否 teleport 到 bodybooleantrue
append-toteleport 挂载目标;传入后会覆盖 append-to-bodystring | HTMLElement'body'
modal是否显示遮罩层booleantrue
modal-class遮罩层自定义类名,仅在 modal=true 时生效string''
modal-penetrable无遮罩时是否允许背景继续点击booleanfalse
close-on-overlay点击遮罩是否关闭booleantrue
close-on-click-modal点击遮罩是否关闭的别名配置,优先级高于 close-on-overlaybooleanundefined
close-on-esc按下 Escape 是否关闭booleantrue
close-on-press-escapeEscape 关闭的别名配置,优先级高于 close-on-escbooleanundefined
open-delay打开延迟,单位毫秒number0
close-delay关闭延迟,单位毫秒number0
destroy-on-close关闭后是否销毁内容booleanfalse
show-close是否显示右上角关闭按钮booleantrue
lock-scroll打开时是否锁定 body 滚动booleantrue
with-header是否渲染默认头部容器booleantrue
before-close关闭前拦截函数,第二个参数会给出触发来源:closebackdropescapeprogrammaticDrawerProps["beforeClose"]undefined
resizable是否允许拖动边缘调整尺寸booleanfalse
custom-class面板自定义类名的兼容别名,建议改用组件原生 classstring''
header-class头部容器自定义类名string''
body-class主体容器自定义类名string''
footer-class底部容器自定义类名string''
z-index指定抽屉层级numberundefined
header-aria-level默认标题节点的 aria-levelstring | number2
modal-fade是否保留遮罩层淡入淡出booleantrue
close-icon关闭按钮图标,使用图标字符串string'mdi:close'
fullscreen是否让抽屉占满整个视口booleanfalse
transition自定义过渡配置,支持过渡名或 Vue Transition 对象DrawerTransition'xy-drawer-fade'

Drawer Events

事件说明参数
update:model-value开关状态变化DrawerModelValueChangeHandler
open打开时触发
opened进入完成后触发
close关闭时触发
closed离开完成后触发
open-auto-focus抽屉打开并完成初始聚焦后触发
close-auto-focus抽屉关闭并恢复焦点后触发
resize-start开始拖拽尺寸时触发DrawerResizeHandler
resize拖拽尺寸过程中触发DrawerResizeHandler
resize-end结束拖拽尺寸时触发DrawerResizeHandler

Drawer Slots

插槽说明
header自定义头部,插槽参数为 DrawerHeaderSlotProps
default主体内容
footer底部操作区
titleheader 类似的兼容插槽,仅用于对齐旧用法,建议优先使用 header;插槽参数为 DrawerTitleSlotProps

Drawer Exposes

名称说明类型
handleClose主动触发关闭流程,会经过 before-close 拦截DrawerInstance["handleClose"]
afterEnter进入完成回调的兼容 expose,建议优先使用 opened 事件DrawerInstance["afterEnter"]
afterLeave离开完成回调的兼容 expose,建议优先使用 closed 事件DrawerInstance["afterLeave"]