Skip to content

抽屉 Drawer

屏幕边缘滑出的浮层面板,承载查看详情、编辑表单等内容,不中断当前操作流。

基础用法

通过 placement 属性设置抽屉弹出方向,支持 right(默认)、leftupdown 四个方向。

vue
<template>
  <bp-space :size="16">
    <bp-button @click="handleOpen('right')">右侧弹出</bp-button>
    <bp-button @click="handleOpen('left')">左侧弹出</bp-button>
  </bp-space>

  <bp-drawer v-model="show" :placement title="基础抽屉">
    <p>这是一个基础的抽屉组件。</p>
  </bp-drawer>
</template>

<script setup lang="ts">
import { ref } from "vue";

const show = ref(false);
const placement = ref("right");

const handleOpen = (p: string) => {
  placement.value = p;
  show.value = true;
};
</script>

弹出方向

分别从四个方向打开抽屉,左右方向通过 width 控制宽度,上下方向通过 height 控制高度。

vue
<template>
  <bp-space :size="16">
    <bp-button @click="handleOpen('right')">右侧弹出</bp-button>
    <bp-button @click="handleOpen('left')">左侧弹出</bp-button>
    <bp-button @click="handleOpen('up')">上方弹出</bp-button>
    <bp-button @click="handleOpen('down')">下方弹出</bp-button>
  </bp-space>

  <bp-drawer v-model="show" :placement title="弹出方向">
    <p>当前弹出方向:{{ placement }}</p>
  </bp-drawer>
</template>

<script setup lang="ts">
import { ref } from "vue";

const show = ref(false);
const placement = ref("right");

const handleOpen = (p: string) => {
  placement.value = p;
  show.value = true;
};
</script>

自定义插槽

使用 headerfooter 和默认插槽自定义抽屉的头部、底部和内容区域。

vue
<template>
  <bp-space :size="16">
    <bp-button @click="showCustom = true">自定义内容</bp-button>
    <bp-button @click="showHeader = true">自定义头部</bp-button>
    <bp-button @click="showFooter = true">自定义底部</bp-button>
  </bp-space>

  <bp-drawer v-model="showCustom" title="用户详情">
    <div class="custom-content">
      <p><strong>姓名:</strong>张三</p>
      <p><strong>邮箱:</strong>zhangsan@example.com</p>
      <p><strong>部门:</strong>技术部</p>
    </div>
  </bp-drawer>

  <bp-drawer v-model="showHeader" title="自定义头部">
    <template #header>
      <div class="custom-header">
        <IconStarFill size="18" style="color: #f7ba2a" />
        <span>自定义标题区域</span>
      </div>
    </template>
    <p>头部区域使用了自定义插槽。</p>
  </bp-drawer>

  <bp-drawer v-model="showFooter" title="自定义底部">
    <p>底部使用了自定义插槽。</p>
    <template #footer>
      <bp-button type="secondary" @click="showFooter = false">关闭</bp-button>
      <bp-button status="danger" @click="showFooter = false">删除</bp-button>
    </template>
  </bp-drawer>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { IconStarFill } from "birdpaper-icon";

const showCustom = ref(false);
const showHeader = ref(false);
const showFooter = ref(false);
</script>

<style lang="scss" scoped>
.custom-content {
  p {
    line-height: 2.2;
    border-bottom: 1px solid #f0f0f0;
  }
}

.custom-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}
</style>

异步确认

通过 on-before-ok 回调实现异步确认,确认按钮会自动进入 loading 状态。返回 true 关闭抽屉,返回 false 则保持打开。

vue
<template>
  <bp-button @click="show = true">异步确认</bp-button>

  <bp-drawer v-model="show" title="提交确认" :on-before-ok="handleBeforeOk">
    <p>点击确认后将执行异步操作,确认按钮会自动进入 loading 状态。</p>
  </bp-drawer>
</template>

<script setup lang="ts">
import { ref } from "vue";

const show = ref(false);

const handleBeforeOk = async () => {
  await new Promise((resolve) => setTimeout(resolve, 2000));
  return true;
};
</script>

Drawer 属性

v-model抽屉是否可见
Boolean
--
title抽屉标题
String
标题-
width抽屉宽度(left/right 方向生效)
String
360px-
height抽屉高度(up/down 方向生效)
String
360px-
placement抽屉弹出方向
String
right-
hide-footer是否隐藏底部区域
Boolean
--
hide-close是否隐藏关闭按钮
Boolean
--
border是否显示边框
Boolean
--
mask-closable点击遮罩是否关闭抽屉
Boolean
true-
ok-text确认按钮文字
String
确认-
cancel-text取消按钮文字
String
取消-
on-before-ok确认前的异步回调,返回 true 关闭抽屉,返回 false 保持打开。按钮自动进入 loading 状态
Function
--

Drawer 事件

cancel点击取消或关闭按钮时触发--
confirm点击确认按钮后触发--

Drawer 插槽

default抽屉内容区域--
header自定义头部区域--
footer自定义底部按钮区域--