---
title: Drawer 抽屉
description: 从屏幕边缘滑出的面板,支持四个方向与边缘拖拽调尺寸
---
# Drawer 抽屉
`Drawer` 从屏幕边缘滑出,视觉重量比 [Modal](/ui/overlay/modal) 轻:它遮挡的是边缘而不是整个画面,用户仍能看到部分页面内容。
## 何时使用
- 长表单、筛选条件、详情信息:内容多但不需要完全接管屏幕时;
- 需要与页面内容对照查看时(抽屉不会把页面完全遮住);
- 必须阻断用户操作、或需要强确认时,用 Modal。
## 基础用法
`v-model:open` 控制显隐;`cancel` 表示「被关闭」(遮罩 / Esc / 关闭按钮)。
## 四个方向
`placement` 支持 `right`(默认)/ `left` / `top` / `bottom`;左右方向用 `width`,上下方向用 `height` 控制尺寸,缩放手柄也会跟着换方向。
## 自定义尺寸
尺寸接受数字(px)或任意 CSS 长度(`'60%'`、`'48rem'`);`resizable=false` 可以关掉边缘拖拽。
## 底部动作与补充信息
`#footer` 放底部动作区;`#extra` 在标题下方补充信息(如「已选 2 个条件」)。
## Modal 还是 Drawer?
| | Modal | Drawer |
| --- | --- | --- |
| 遮挡范围 | 整个页面(居中/贴顶面板) | 一侧边缘 |
| 适合内容 | 短表单、确认、需要强聚焦 | 长表单、筛选、详情、多步骤 |
| 页面上下文 | 被遮罩挡住 | 仍可见(便于对照) |
| 尺寸调整 | 四边缩放 + 全屏 | 单边拖拽 |
## API
### Props
| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `open` | `boolean` | — | 受控打开状态;不传即非受控 |
| `defaultOpen` | `boolean` | `false` | 非受控时的初始状态 |
| `title` | `string` | `''` | 标题 |
| `placement` | `'left' \| 'right' \| 'top' \| 'bottom'` | `'right'` | 滑出方向 |
| `width` | `number \| string` | `378` | 宽度(`left` / `right` 生效) |
| `height` | `number \| string` | `378` | 高度(`top` / `bottom` 生效) |
| `mask` | `boolean` | `true` | 是否显示遮罩 |
| `maskClosable` | `boolean` | `true` | 点击遮罩关闭 |
| `keyboard` | `boolean` | `true` | Esc 关闭 |
| `closable` | `boolean` | `true` | 显示右上角关闭按钮 |
| `resizable` | `boolean` | `true` | 允许拖拽面板边缘调整尺寸 |
| `popupContainer` | `PopupContainer` | ConfigProvider 配置 | 挂载容器,默认 `body` |
### Events
| 名称 | 参数 | 说明 |
| --- | --- | --- |
| `update:open` | `(open: boolean)` | 打开状态变化 |
| `cancel` | `()` | 遮罩 / Esc / 关闭按钮触发的关闭意图(内容区的操作按钮不会触发它) |
| `closed` | `()` | 退场动画结束(滚动已解锁、焦点已归还) |
### Slots
| 名称 | 参数 | 说明 |
| --- | --- | --- |
| `default` | — | 内容区(可滚动) |
| `extra` | — | 标题下方的补充信息 |
| `footer` | — | 底部动作区 |
### 类型定义
```ts
export type DrawerPlacement = 'left' | 'right' | 'top' | 'bottom'
export interface DrawerProps {
open?: boolean
defaultOpen?: boolean
title?: string
placement?: DrawerPlacement
width?: number | string
height?: number | string
mask?: boolean
maskClosable?: boolean
keyboard?: boolean
closable?: boolean
resizable?: boolean
popupContainer?: PopupContainer
}
```
## 实现说明
- 面板贴边、容器 `pointer-events: none`,只有面板自身可交互——这样「抽屉打开时页面其他区域仍可点击」,符合抽屉"不接管屏幕"的定位;
- 滑入/滑出用 `transform: translateX/Y(±100%)`,只过渡 `transform`,因此不会有布局抖动;
- 缩放手柄只改一个轴(左右改宽、上下改高),并按视口上限夹取;关闭后尺寸复位,下次打开不继承;
- 焦点与滚动处理与 Modal 共用同一套工具(焦点陷阱、滚动锁引用计数、退场后再归还焦点)。