抽屉
屏幕边缘滑出的浮层面板,通常用于在当前任务状态下进行一些临时性的操作。
基础用法
最简单的调用方式,默认从右侧滑出。
vue
<script setup>
import { ref } from 'vue'
const visible = ref(false)
</script>
<template>
<TuiButton @click="visible = true">打开抽屉</TuiButton>
<TuiDrawer v-model="visible">
<div style="padding: 20px;">
这是一个基础抽屉。
</div>
</TuiDrawer>
</template>滑出方向
通过 direction 属性支持四个方向的滑出方式:
rtl: Right to Left (默认)ltr: Left to Rightttb: Top to Bottombtt: Bottom to Top
vue
<script setup>
import { reactive } from 'vue'
const state = reactive({
rtl: false,
ltr: false,
ttb: false,
btt: false
})
</script>
<template>
<div class="demo-box">
<TuiButton @click="state.rtl = true">从右滑出 (Default)</TuiButton>
<TuiButton @click="state.ltr = true">从左滑出</TuiButton>
<TuiButton @click="state.ttb = true">从上滑出</TuiButton>
<TuiButton @click="state.btt = true">从下滑出</TuiButton>
</div>
<TuiDrawer v-model="state.rtl" direction="rtl">
<p>Right to Left</p>
</TuiDrawer>
<TuiDrawer v-model="state.ltr" direction="ltr">
<p>Left to Right</p>
</TuiDrawer>
<TuiDrawer v-model="state.ttb" direction="ttb" size="40%">
<p>Top to Bottom</p>
</TuiDrawer>
<TuiDrawer v-model="state.btt" direction="btt" size="40%">
<p>Bottom to Top</p>
</TuiDrawer>
</template>尺寸与内边距
可以通过 size 控制抽屉的宽度(左右模式)或高度(上下模式),支持像素数值或百分比字符串。通过 padding 统一控制内容区的内边距。
vue
<script setup>
import { reactive } from 'vue'
const state = reactive({
customPx: false,
customPercent: false
})
</script>
<template>
<TuiButton @click="state.customPx = true">固定宽度 400px</TuiButton>
<TuiButton @click="state.customPercent = true">百分比 60%</TuiButton>
<TuiDrawer
v-model="state.customPx"
:size="400"
:padding="50"
>
<p>Width: 400px</p>
<p>Padding: 50px</p>
</TuiDrawer>
<TuiDrawer v-model="state.customPercent" size="60%">
<p>Width: 60%</p>
</TuiDrawer>
</template>交互行为
提供了丰富的 Props 来控制抽屉的关闭逻辑和遮罩行为,适用于不同的交互场景。
- showClose: 是否显示右上角的关闭按钮。
- closeOnBackdrop: 点击遮罩层是否关闭。
- closeOnEsc: 按下 ESC 键是否关闭。
- modal: 是否显示黑色遮罩层。
vue
<script setup>
import { ref } from 'vue'
const visible = ref(false)
const config = {
showClose: true, // 显示关闭按钮
closeOnBackdrop: false, // 禁止点击遮罩关闭
closeOnEsc: true // 允许 ESC 关闭
}
</script>
<template>
<TuiButton @click="visible = true">打开强交互抽屉</TuiButton>
<TuiDrawer v-model="visible" v-bind="config">
<h3>强制操作</h3>
<p>点击遮罩无法关闭,请点击右上角关闭按钮或按 ESC。</p>
</TuiDrawer>
</template>API 参考
Props
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | (v-model) 是否显示抽屉 | Boolean | — |
| direction | 打开方向,可选值: 'rtl', 'ltr', 'ttb', 'btt' | String | 'rtl' |
| size | 抽屉的尺寸(宽度或高度),支持数字(px)或百分比字符串 | String / Number | 'auto' |
| title | 抽屉标题(如需复杂标题建议使用 Slot) | String | — |
| padding | 抽屉主体内容的内边距 (px) | Number | 30 |
| modal | 是否显示遮罩层 | Boolean | true |
| showClose | 是否显示关闭按钮 | Boolean | false |
| closeOnBackdrop | 点击遮罩层是否触发关闭 | Boolean | true |
| closeOnEsc | 按下 Esc 键是否触发关闭 | Boolean | true |
| appendTo | 指定挂载的 DOM 节点选择器 | String | — |
| zIndex | 设置抽屉的 z-index 层级 | Number | 2001 |
| className | 自定义类名 | String | — |
Emits
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| update:modelValue | 绑定值变化时触发 | value: boolean |
| open | 抽屉打开时触发 | — |
| close | 抽屉关闭时触发 | — |
Slots
| 插槽名 | 说明 |
|---|---|
| default | 抽屉的主体内容 |
全局交互监控
TuiDrawer 组件通过集成 TechUI 全局服务(TuiService),利用 escCounter 和 clickCounter 两个核心参数来实现智能的闭合管理:
- ESC 响应 (
escCounter):组件实时监听全局 ESC 信号。当closeOnEsc属性为true时,按下 Esc 键会触发escCounter更新,从而自动关闭当前活跃的抽屉。 - 智能点击检测 (
clickCounter): - 遮罩层点击:当
modal为true且closeOnBackdrop为true时,组件会检测点击目标是否为遮罩层本身,如果是则触发关闭。 - 外部点击 (无遮罩模式):当
modal为false时,组件会利用全局的clickTarget进行精准的包含检测。只有当点击目标既不在抽屉面板内部,也不在触发元素内部时,才会触发关闭逻辑。这使得无遮罩抽屉也能拥有自然的“点击外部关闭”体验。