Skip to content

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>
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是否显示抽屉booleanfalse
disabled是否禁用 Teleportbooleanfalse
placement抽屉弹出位置'top' | 'right' | 'bottom' | 'left''right'
title标题string''
mask是否显示遮罩booleantrue
showFooter是否显示底部操作区booleantrue
hideCancel是否隐藏默认取消按钮booleanfalse
maskToClose点击遮罩是否关闭booleantrue
escToClose按下 Esc 是否关闭booleantrue
destroyOnClosed关闭后是否销毁内容booleantrue
width左右抽屉宽度string | number340
height上下抽屉高度string | number340
okText确认按钮文案string'确认'
cancelText取消按钮文案string'取消'
okLoading确认按钮是否 loadingbooleanfalse
okButtonProps确认按钮 propsButtonProps-
cancelButtonProps取消按钮 propsButtonProps-
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-
bodyClassbody 自定义类名string | array | object-
bodyStylebody 自定义样式StyleValue-
showClose是否显示关闭按钮booleantrue

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、自定义关闭图标等能力后续再评估。