Skip to content

Drawer 抽屉

抽屉从屏幕边缘滑入,用于承载复杂操作或展示额外内容,不影响当前页面主体。

基础用法

通过 v-model 控制显示状态。默认从右侧滑入。

<!-- src/demo/drawer/Basic.vue -->
<template>
    <div>
        <hy-button type="primary" @click="drawer = true">打开抽屉</hy-button>

        <hy-drawer v-model="drawer" title="基础抽屉">
            <p>这是抽屉的内容区域</p>
            <p>可以放置表单、列表、或其他复杂组件</p>
        </hy-drawer>
    </div>
</template>

<script setup>
import { ref } from 'vue'
const drawer = ref(false)
</script>

不同方向

通过 direction 属性设置抽屉弹出方向:left-to-rightright-to-left(默认)、top-to-bottombottom-to-top

<!-- src/demo/drawer/Direction.vue -->
<template>
  <div>
    <hy-button @click="drawer1 = true">从左往右</hy-button>
    <hy-button @click="drawer2 = true">从上往下</hy-button>
    <hy-button @click="drawer3 = true">从下往上</hy-button>

    <hy-drawer v-model="drawer1" title="左侧抽屉" direction="left-to-right">
      <p>从左侧滑入</p>
    </hy-drawer>

    <hy-drawer v-model="drawer2" title="顶部抽屉" direction="top-to-bottom" size="200px">
      <p>从顶部滑入</p>
    </hy-drawer>

    <hy-drawer v-model="drawer3" title="底部抽屉" direction="bottom-to-top" size="25%">
      <p>从底部滑入</p>
    </hy-drawer>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const drawer1 = ref(false)
const drawer2 = ref(false)
const drawer3 = ref(false)
</script>

自定义标题和内容

支持通过 #title 和默认插槽自定义标题和内容区域。

<!-- src/demo/drawer/Custom.vue -->
<template>
  <div>
    <hy-button type="success" @click="drawer = true">自定义内容</hy-button>
    
    <hy-drawer v-model="drawer">
      <template #title>
        <span class="custom-title">🎨 自定义标题</span>
      </template>
      
      <div class="custom-content">
        <hy-input v-model="inputValue" placeholder="输入内容" />
        <p class="mt-4">当前输入:{{ inputValue }}</p>
      </div>
    </hy-drawer>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const drawer = ref(false)
const inputValue = ref('')
</script>

<style scoped>
.custom-title {
  color: #007bff;
  font-weight: bold;
  font-size: 18px;
}

.custom-content {
  padding: 20px;
  background: #f8f9fa;
  border-radius: 8px;
}

.mt-4 {
  margin-top: 1rem;
}
</style>

自定义底部区域

通过 #footer 插槽自定义底部操作按钮。

<!-- src/demo/drawer/Footer.vue -->
<template>
  <div>
    <hy-button type="warning" @click="drawer = true">自定义底部</hy-button>
    
    <hy-drawer v-model="drawer" title="确认操作">
      <p>你确定要执行此操作吗?</p>
      <p>此操作不可逆,请谨慎操作。</p>
      
      <template #footer>
        <div class="footer-actions">
          <hy-button plain @click="drawer = false">取消</hy-button>
          <hy-button type="danger" @click="handleConfirm">确认</hy-button>
        </div>
      </template>
    </hy-drawer>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const drawer = ref(false)

function handleConfirm() {
  alert('操作已执行')
  drawer.value = false
}
</script>

<style scoped>
.footer-actions {
  text-align: right;
  padding: 16px 20px;
  border-top: 1px solid #ebeef5;
  background: #f8f9fa;
}
</style>

禁用关闭按钮

设置 :show-close="false" 可隐藏右上角关闭按钮。

<!-- src/demo/drawer/NoCloseBtn.vue -->
<template>
  <div>
    <hy-button type="danger" @click="drawer = true">无关闭按钮</hy-button>
    
    <hy-drawer v-model="drawer" title="强制阅读" :show-close="false">
      <div class="read-content">
        <h4>📜 使用条款</h4>
        <ol>
          <li>请仔细阅读以下条款</li>
          <li>同意后方可继续使用</li>
          <li>如有疑问请联系客服</li>
        </ol>
      </div>
      
      <template #footer>
        <div class="footer-actions">
          <hy-button type="primary" @click="drawer = false">同意并继续</hy-button>
        </div>
      </template>
    </hy-drawer>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const drawer = ref(false)
</script>

<style scoped>
.read-content {
  padding: 20px;
}

.read-content h4 {
  color: #67c23a;
  margin: 0 0 15px 0;
}

.read-content ol {
  padding-left: 20px;
}

.read-content li {
  margin: 5px 0;
}

.footer-actions {
  text-align: right;
  padding: 16px 20px;
  border-top: 1px solid #ebeef5;
  background: #f8f9fa;
}
</style>

自定义尺寸

通过 size 属性设置抽屉宽度(左右方向)或高度(上下方向),支持 px / %

<!-- src/demo/drawer/Size.vue -->
<template>
  <div>
    <hy-button @click="drawer1 = true">窄抽屉 (200px)</hy-button>
    <hy-button @click="drawer2 = true">宽抽屉 (50%)</hy-button>
    <hy-button @click="drawer3 = true">高抽屉 (30%)</hy-button>

    <hy-drawer v-model="drawer1" title="窄抽屉" size="200px">
      <div class="size-content">
        <p>宽度: 200px</p>
        <p>适合显示简洁内容</p>
      </div>
    </hy-drawer>

    <hy-drawer v-model="drawer2" title="宽抽屉" direction="left-to-right" size="50%">
      <div class="size-content">
        <p>宽度: 50%</p>
        <p>适合显示复杂表单或列表</p>
      </div>
    </hy-drawer>

    <hy-drawer v-model="drawer3" title="高抽屉" direction="top-to-bottom" size="30%">
      <div class="size-content">
        <p>高度: 30%</p>
        <p>适合显示通知或快捷操作</p>
      </div>
    </hy-drawer>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const drawer1 = ref(false)
const drawer2 = ref(false)
const drawer3 = ref(false)
</script>

<style scoped>
.size-content {
  padding: 20px;
}

.size-content p {
  margin: 5px 0;
}
</style>

Drawer API

Props

NameDescriptionTypeDefault
modelValue是否显示抽屉booleanfalse
title抽屉标题string
direction弹出方向enum - 'left-to-right'|'right-to-left'|'top-to-bottom'|'bottom-to-top'right-to-left
size抽屉尺寸(宽/高)string360px
show-close是否显示关闭按钮booleantrue
mask-closable是否允许点击遮罩关闭booleantrue

Events

NameDescriptionType
update:modelValue抽屉显示状态更新(value: boolean) => void
close抽屉关闭时触发() => void

Slots

NameDescription
default抽屉内容区域
title自定义标题内容
footer自定义底部操作区域

Expose

NameDescriptionType
open打开抽屉() => void
close关闭抽屉() => void