Skip to content

FxDrawer 抽屉

从屏幕边缘滑出的浮层。不依赖任何 UI 框架,复用 FxDialog 的核心逻辑,支持四向打开与可调整大小。

基础用法

通过 v-model 控制显隐,title 设置标题。默认从右侧滑出,尺寸 30%。before-close 可拦截关闭。

打开方向

direction 支持 rtl(右)/ ltr(左)/ ttb(上)/ btt(下),size 控制尺寸。

无标题

设置 with-headerfalse 可隐藏标题栏,获得更大空间。如需无障碍,仍应设置 title 属性。

自定义内容

与 Dialog 一样,Drawer 可承载任意内容,包括表单。

自定义标题

header 插槽可自定义标题区。

标题栏额外按钮(扩展)

header-extra 插槽位于关闭按钮左侧,用于放置自定义按钮。

全屏(扩展)

fullscreen 控制是否全屏铺满。FxDrawer 额外提供:fullscreen-button(默认开启,显示标题栏全屏切换按钮)、default-fullscreen(打开时默认全屏)、v-model:fullscreen(受控双向)。全屏时抽屉铺满整个屏幕,sizedirection 失效。

可调整大小

设置 resizable 后,抽屉边缘出现拖拽条,可拖动调整大小。

嵌套抽屉

嵌套抽屉时内层需设置 append-to-body

遮罩

modalfalse 时隐藏遮罩;modal-penetrable 使遮罩可点击穿透(需 modal=false)。

局部引入

ts
import { FxDrawer } from "@fx/components"

API

Attributes

继承 FxDialog 全部 Attributes,并扩展:

名称说明类型默认值
model-value / v-model是否显示booleanfalse
title标题(也可用 header / title 插槽)string
direction打开方向'rtl' | 'ltr' | 'ttb' | 'btt'rtl
size抽屉尺寸(数字为 px,字符串建议 'x%')string | number30%
with-header是否显示 header(隐藏可获得更大空间)booleantrue
resizable是否可调整大小booleanfalse
modal-fade遮罩层淡入淡出开关booleantrue
fullscreen是否全屏铺满(支持 v-model:fullscreen,扩展)booleanfalse
fullscreen-button是否显示全屏切换按钮(扩展)booleantrue
default-fullscreen打开时是否默认全屏(扩展)booleanfalse
modal是否显示遮罩booleantrue
modal-penetrable遮罩是否可穿透(需 modal=falsebooleanfalse
modal-class遮罩自定义类名string
header-class / body-class / footer-classheader / 正文 / 底部自定义类名string
append-to-body是否挂载到 body(嵌套抽屉需置 truebooleanfalse
append-to挂载目标string | HTMLElementbody
lock-scroll是否锁定 body 滚动booleantrue
open-delay / close-delay打开 / 关闭延时(ms)number0
close-on-click-modal点击遮罩是否关闭booleantrue
close-on-press-escape按 ESC 是否关闭booleantrue
show-close是否显示关闭按钮booleantrue
before-close关闭前回调,调用 done() 关闭、done(true) 取消(done: (cancel?: boolean) => void) => void
destroy-on-close关闭时销毁内容booleanfalse
trap-focus是否在抽屉内捕获焦点(焦点陷阱)booleanfalse
transition自定义过渡动画(字符串名或 TransitionProps)string | TransitionProps
z-index层级number自增
header-aria-levelheader 的 aria-levelstring2

Events

继承 FxDialog 全部 Events,并扩展:

名称说明类型
update:modelValue显隐变化(value: boolean)
update:fullscreen全屏状态变化(扩展)(value: boolean)
fullscreen-change全屏状态变化(扩展)(value: boolean)
open / opened / close / closed打开 / 关闭生命周期() => void
open-auto-focus / close-auto-focus聚焦回调() => void
resize-start开始调整大小(evt: MouseEvent, size: number)
resize调整大小中(evt: MouseEvent, size: number)
resize-end结束调整大小(evt: MouseEvent, size: number)

Slots

名称说明作用域参数
default抽屉正文
header标题区(覆盖默认标题与全屏按钮,不覆盖关闭按钮)close: () => void titleId: string titleClass: string
header-extra标题栏额外按钮区(位于全屏 / 关闭按钮左侧,扩展)
footer底部区
title标题(已废弃,建议改用 header

Exposes

名称说明类型
handleClose触发关闭(会调用 before-close)() => void

实现说明

  • 核心复用:抽屉复用 FxDialoguseDialog Hook 处理显隐、遮罩、焦点陷阱、滚动锁定、z-index 自增等通用弹层逻辑,自身只负责四向定位与可调整大小。
  • 尺寸方向useResizable 根据 direction 判断横向(ltr / rtl)或纵向(ttb / btt),按方向在抽屉面板上设置 widthheight。横向抽屉撑满高度、纵向抽屉撑满宽度,再用 top/right/bottom/left 锚定到对应边缘。
  • 可调整大小resizable 开启后渲染一条贴边的拖拽条(fx-drawer__dragger),mousedown 锁定起始尺寸与坐标,mousemove 按方向取 offsetXoffsetY 并以方向符号累加,最终尺寸在 [4, 窗口尺寸] 区间内 clamp。拖动期间挂 is-dragging 类关闭过渡,避免拖拽抖动。resize-start / resize / resize-end 三个事件携带 MouseEvent 与当前尺寸。
  • 进入 / 离开动画fx-drawer-fade 过渡。enter-from / leave-to 阶段把遮罩背景置透明并按方向位移抽屉面板(ltr 左移 100%、rtl 右移 100%、ttb 上移 100%、btt 下移 100%),duration-slow 时长内完成滑入滑出。
  • 视觉规格:背景走 --color-surface、阴影走 --shadow-card、文字走 --color-text-primary,标题与正文统一 --fx-drawer-padding-primary(默认 20px)内边距,标题区下方留 32px 间距,底部区域顶部 10px。所有取值统一走 @fx/styles 设计 token,不引用任何第三方 UI 库变量。
  • fx 增强(向后兼容,默认值保持原行为):标题栏右侧的「全屏 / 退出全屏」按钮(fullscreen-button 默认开启)、header-extra 插槽用于放置自定义工具按钮、fullscreen / default-fullscreen / v-model:fullscreen 三种全屏控制方式。全屏态挂 is-fullscreen 类,面板铺满整个屏幕,此时 sizedirection 的尺寸约束失效。
  • 无障碍:面板挂 role="dialog"aria-modal="true",标题存在时以 aria-label 标注,否则用 aria-labelledby 关联 titleId;标题节点 role="heading" + header-aria-level;首焦元素 fx-drawer__sr-focus 在聚焦时去除默认轮廓。