Drawer 抽屉
从屏幕边缘展开内容,适合详情、编辑和辅助配置。
何时使用
- 需要在不离开当前页面的情况下查看详情、编辑表单或配置参数。
- 内容比 Popconfirm、Tooltip 更复杂,但又不需要 Dialog 那样强打断。
- 希望任务完成后回到原页面上下文。
基础用法
vue
<template>
<x-button type="primary" @click="visible = true">打开抽屉</x-button>
<x-drawer v-model="visible" title="详情">
抽屉内容
</x-drawer>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const visible = ref(false);
</script>位置与尺寸
vue
<template>
<x-drawer v-model="visible" placement="bottom" height="300px" title="底部抽屉">
内容
</x-drawer>
</template>受控与事件
vue
<template>
<x-drawer
v-model="visible"
title="事件记录"
@ok="handleOk"
@cancel="handleCancel"
@close="handleClose"
>
内容
</x-drawer>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const visible = ref(false);
const handleOk = (event?: Event) => console.log('ok', event);
const handleCancel = (event?: Event) => console.log('cancel', event);
const handleClose = (action: 'ok' | 'cancel', event?: Event) => console.log(action, event);
</script>异步关闭
vue
<template>
<x-drawer v-model="visible" title="提交确认" :on-before-ok="beforeOk">
点击确认后等待异步校验。
</x-drawer>
</template>
<script setup lang="ts">
const beforeOk = async () => {
await new Promise((resolve) => window.setTimeout(resolve, 1000));
return true;
};
</script>遮罩和关闭
vue
<template>
<x-drawer
v-model="visible"
title="无遮罩"
:mask="false"
:mask-to-close="false"
:esc-to-close="false"
:show-close="false"
>
内容
</x-drawer>
</template>自定义 Footer
vue
<template>
<x-drawer v-model="visible" title="自定义 Footer">
内容
<template #footer="{ ok, cancel, loadingObj }">
<x-space>
<x-button type="text" :loading="loadingObj.cancel" @click="cancel">
稍后处理
</x-button>
<x-button type="primary" :loading="loadingObj.ok" @click="ok">
保存
</x-button>
</x-space>
</template>
</x-drawer>
</template>局部容器
局部容器
vue
<template>
<x-button @click="visible = true">打开局部抽屉</x-button>
<div id="drawer-local-container" class="demo-drawer-local-container">
局部容器
</div>
<x-drawer
v-model="visible"
render-to="#drawer-local-container"
title="局部抽屉"
width="260px"
>
内容
</x-drawer>
</template>按需导入
ts
import { Drawer } from 'x-next';Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
modelValue | 是否显示抽屉 | boolean | false |
disabled | 是否禁用 Teleport | boolean | false |
placement | 抽屉弹出位置 | 'top' | 'right' | 'bottom' | 'left' | 'right' |
title | 标题 | string | '' |
mask | 是否显示遮罩 | boolean | true |
showFooter | 是否显示底部操作区 | boolean | true |
hideCancel | 是否隐藏默认取消按钮 | boolean | false |
maskToClose | 点击遮罩是否关闭 | boolean | true |
escToClose | 按下 Esc 是否关闭 | boolean | true |
destroyOnClosed | 关闭后是否销毁内容 | boolean | true |
width | 左右抽屉宽度 | string | number | 340 |
height | 上下抽屉高度 | string | number | 340 |
okText | 确认按钮文案 | string | '确认' |
cancelText | 取消按钮文案 | string | '取消' |
okLoading | 确认按钮是否 loading | boolean | false |
okButtonProps | 确认按钮 props | ButtonProps | - |
cancelButtonProps | 取消按钮 props | ButtonProps | - |
onBeforeOk | 确认前拦截,返回 false 阻止关闭 | (event?: Event) => boolean | void | Promise<boolean | void> | - |
onBeforeCancel | 取消前拦截,返回 false 阻止关闭 | (event?: Event) => boolean | void | Promise<boolean | void> | - |
renderTo | 挂载容器 | string | HTMLElement | 'body' |
popupClass | 最外层自定义类名 | string | - |
drawerStyle | 最外层样式 | CSSProperties | - |
bodyClass | body 自定义类名 | string | array | object | - |
bodyStyle | body 自定义样式 | StyleValue | - |
showClose | 是否显示关闭按钮 | boolean | true |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
update:modelValue | 显隐状态变化时触发 | value: boolean |
open | 打开时触发 | - |
opened | 打开动画结束后触发 | - |
ok | 点击确认且未被拦截时触发 | event?: Event |
cancel | 点击取消、关闭、遮罩或 Esc 且未被拦截时触发 | event?: Event |
close | 请求关闭且未被拦截时触发 | action: 'cancel' | 'ok', event?: Event |
closed | 关闭动画结束后触发 | - |
Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
default | 抽屉主体内容 | - |
title | 自定义标题 | - |
footer | 自定义底部操作区 | { ok, cancel, loadingObj } |
fill | 完全自定义抽屉内部结构 | - |
已知限制
- 当前暂不提供命令式
Drawer.open()。 - 多层 Drawer push、
extra、自定义关闭图标等能力后续再评估。