Skip to content

抽屉

屏幕边缘滑出的浮层面板,通常用于在当前任务状态下进行一些临时性的操作。

基础用法

最简单的调用方式,默认从右侧滑出。

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 Right
  • ttb: Top to Bottom
  • btt: 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)Number30
modal是否显示遮罩层Booleantrue
showClose是否显示关闭按钮Booleanfalse
closeOnBackdrop点击遮罩层是否触发关闭Booleantrue
closeOnEsc按下 Esc 键是否触发关闭Booleantrue
appendTo指定挂载的 DOM 节点选择器String
zIndex设置抽屉的 z-index 层级Number2001
className自定义类名String

Emits

事件名说明回调参数
update:modelValue绑定值变化时触发value: boolean
open抽屉打开时触发
close抽屉关闭时触发

Slots

插槽名说明
default抽屉的主体内容

全局交互监控

TuiDrawer 组件通过集成 TechUI 全局服务(TuiService),利用 escCounterclickCounter 两个核心参数来实现智能的闭合管理:

  • ESC 响应 (escCounter):组件实时监听全局 ESC 信号。当 closeOnEsc 属性为 true 时,按下 Esc 键会触发 escCounter 更新,从而自动关闭当前活跃的抽屉。
  • 智能点击检测 (clickCounter)
  • 遮罩层点击:当 modaltruecloseOnBackdroptrue 时,组件会检测点击目标是否为遮罩层本身,如果是则触发关闭。
  • 外部点击 (无遮罩模式):当 modalfalse 时,组件会利用全局的 clickTarget 进行精准的包含检测。只有当点击目标既不在抽屉面板内部,也不在触发元素内部时,才会触发关闭逻辑。这使得无遮罩抽屉也能拥有自然的“点击外部关闭”体验。