Drawer 抽屉

从屏幕边缘滑出的浮层面板

何时使用

  • 需要侧边抽屉面板承载内容时。

导入

import {
  Drawer,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerDescription,
  DrawerFooter,
  DrawerClose,
  DrawerTrigger,
} from "@reglow/reui";

基础用法

抽屉从父窗体边缘滑入,覆盖住部分父窗体内容。用户在抽屉内操作时不必离开当前任务,操作完成后可以平滑地回到原任务。

<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@reglow/reui";
import {
  Drawer,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerDescription,
  DrawerClose,
} from "@reglow/reui";

const open = ref(false);
</script>

<template>
  <Drawer v-model:open="open" direction="right">
    <DrawerContent>
      <DrawerHeader>
        <DrawerTitle>基础抽屉</DrawerTitle>
        <DrawerDescription>这是抽屉的描述内容</DrawerDescription>
      </DrawerHeader>
      <div class="p-4">
        <p>抽屉内容区域</p>
      </div>
    </DrawerContent>
  </Drawer>
  <Button @click="open = true">打开抽屉</Button>
</template>

自定义位置

点击触发按钮抽屉从相应的位置滑出。

<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@reglow/reui";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from "@reglow/reui";

const open = ref(false);
const direction = ref<"left" | "right" | "top" | "bottom">("left");
</script>

<template>
  <Button @click="direction = 'left'; open = true">左侧</Button>
  <Button @click="direction = 'right'; open = true">右侧</Button>
  <Button @click="direction = 'top'; open = true">顶部</Button>
  <Button @click="direction = 'bottom'; open = true">底部</Button>
  <Drawer v-model:open="open" :direction="direction">
    <DrawerContent>
      <DrawerHeader>
        <DrawerTitle>{{ direction }} 抽屉</DrawerTitle>
      </DrawerHeader>
      <div class="p-4">内容</div>
    </DrawerContent>
  </Drawer>
</template>

预设宽度

抽屉的默认宽度为 378px,另外还提供一个大号抽屉 736px,可以用 size 属性来设置。

<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@reglow/reui";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from "@reglow/reui";

const open = ref(false);
</script>

<template>
  <Button @click="open = true">Large Size (736px)</Button>
  <Drawer v-model:open="open" size="large">
    <DrawerContent>
      <DrawerHeader>
        <DrawerTitle>大号抽屉</DrawerTitle>
      </DrawerHeader>
      <div class="p-4">宽度 736px</div>
    </DrawerContent>
  </Drawer>
</template>

加载中

设置抽屉加载状态,显示骨架屏。

<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@reglow/reui";
import { Drawer, DrawerContent } from "@reglow/reui";

const open = ref(false);
</script>

<template>
  <Button @click="open = true">打开加载中抽屉</Button>
  <Drawer v-model:open="open" :loading="true">
    <DrawerContent>
      <!-- loading=true 时自动显示骨架屏 -->
    </DrawerContent>
  </Drawer>
</template>

额外操作

在抽屉右上角的操作区域,可以使用 extra 属性来实现。

<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@reglow/reui";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerFooter, DrawerClose } from "@reglow/reui";

const open = ref(false);
</script>

<template>
  <Button @click="open = true">额外操作</Button>
  <Drawer v-model:open="open" extra="额外内容">
    <DrawerContent>
      <DrawerHeader>
        <DrawerTitle>带额外操作的抽屉</DrawerTitle>
      </DrawerHeader>
      <div class="p-4">内容区域</div>
      <DrawerFooter class="flex-row justify-end">
        <DrawerClose as-child>
          <Button variant="outline">取消</Button>
        </DrawerClose>
        <Button>提交</Button>
      </DrawerFooter>
    </DrawerContent>
  </Drawer>
</template>

遮罩

通过 mask 控制遮罩效果。

<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@reglow/reui";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from "@reglow/reui";

const open = ref(false);
</script>

<template>
  <Button @click="open = true">无遮罩抽屉</Button>
  <Drawer v-model:open="open" :mask="false">
    <DrawerContent>
      <DrawerHeader>
        <DrawerTitle>无遮罩</DrawerTitle>
      </DrawerHeader>
      <div class="p-4">内容</div>
    </DrawerContent>
  </Drawer>
</template>

抽屉表单

在抽屉中使用表单。

<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@reglow/reui";
import { Input } from "@reglow/reui";
import { Label } from "@reglow/reui";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, DrawerFooter, DrawerClose } from "@reglow/reui";

const open = ref(false);
const form = ref({ name: "", email: "" });
</script>

<template>
  <Button @click="open = true">打开表单抽屉</Button>
  <Drawer v-model:open="open" direction="right" :close-on-overlay-click="false">
    <DrawerContent class="w-[500px] max-w-[95vw]">
      <DrawerHeader>
        <DrawerTitle>新建账户</DrawerTitle>
        <DrawerDescription>请填写以下表单信息</DrawerDescription>
      </DrawerHeader>
      <div class="px-4 py-2 space-y-4 flex-1 overflow-y-auto">
        <div class="space-y-2">
          <Label>姓名</Label>
          <Input v-model="form.name" placeholder="请输入姓名" />
        </div>
        <div class="space-y-2">
          <Label>邮箱</Label>
          <Input v-model="form.email" placeholder="请输入邮箱" />
        </div>
      </div>
      <DrawerFooter class="flex-row justify-end">
        <DrawerClose as-child>
          <Button variant="outline">取消</Button>
        </DrawerClose>
        <Button>提交</Button>
      </DrawerFooter>
    </DrawerContent>
  </Drawer>
</template>

关闭按钮位置

自定义抽屉的关闭按钮位置。

<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@reglow/reui";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from "@reglow/reui";

const open = ref(false);
</script>

<template>
  <Button @click="open = true">关闭按钮在右侧</Button>
  <Drawer v-model:open="open" closable-placement="end">
    <DrawerContent>
      <DrawerHeader>
        <DrawerTitle>关闭按钮在右侧</DrawerTitle>
      </DrawerHeader>
      <div class="p-4">内容</div>
    </DrawerContent>
  </Drawer>
</template>

触发器用法

使用 DrawerTrigger 作为触发器。

<script setup lang="ts">
import { ref } from "vue";
import { Button } from "@reglow/reui";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger } from "@reglow/reui";

const open = ref(false);
</script>

<template>
  <Drawer v-model:open="open">
    <DrawerTrigger as-child>
      <Button>点击打开</Button>
    </DrawerTrigger>
    <DrawerContent>
      <DrawerHeader>
        <DrawerTitle>触发器抽屉</DrawerTitle>
      </DrawerHeader>
      <div class="p-4">内容</div>
    </DrawerContent>
  </Drawer>
</template>

API

Drawer Props

参数说明类型默认值
open (v-model)Drawer 是否可见booleanfalse
direction抽屉的方向'top' | 'right' | 'bottom' | 'left''right'
size预设抽屉宽度(或高度)'default' | 'large' | number | string'default'
mask是否显示遮罩booleantrue
closeOnOverlayClick点击遮罩是否关闭booleantrue
closable是否显示关闭按钮booleantrue
closablePlacement关闭按钮位置'start' | 'end''start'
loading显示骨架屏booleanfalse
title标题string-
extra右上角额外操作区域string-
footer页脚string-
zIndex设置 Drawer 的 z-indexnumber1000
width自定义宽度string | number-
height自定义高度string | number-
destroyOnHidden关闭时销毁子元素booleanfalse

Drawer Events

事件名说明参数
update:open打开状态变化(open: boolean)
afterOpenChange动画结束后回调(open: boolean)

DrawerContent Props

参数说明类型默认值
class自定义内容区域 classstring-
overlayClass自定义遮罩层 classstring-

子组件

组件说明
DrawerContent抽屉内容面板,包含遮罩、动画、关闭按钮、骨架屏
DrawerHeader头部区域
DrawerTitle标题,基于 reka-ui DialogTitle
DrawerDescription描述文字,基于 reka-ui DialogDescription
DrawerFooter底部页脚区域
DrawerClose关闭按钮,基于 reka-ui DialogClose
DrawerTrigger触发器,基于 reka-ui DialogTrigger

预设尺寸

size宽度/高度
default378px
large736px
数值500 -> 500px
字符串'50%'