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-right、right-to-left(默认)、top-to-bottom、bottom-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
| Name | Description | Type | Default |
|---|---|---|---|
| modelValue | 是否显示抽屉 | boolean | false |
| title | 抽屉标题 | string | — |
| direction | 弹出方向 | enum - 'left-to-right'|'right-to-left'|'top-to-bottom'|'bottom-to-top' | right-to-left |
| size | 抽屉尺寸(宽/高) | string | 360px |
| show-close | 是否显示关闭按钮 | boolean | true |
| mask-closable | 是否允许点击遮罩关闭 | boolean | true |
Events
| Name | Description | Type |
|---|---|---|
| update:modelValue | 抽屉显示状态更新 | (value: boolean) => void |
| close | 抽屉关闭时触发 | () => void |
Slots
| Name | Description |
|---|---|
| default | 抽屉内容区域 |
| title | 自定义标题内容 |
| footer | 自定义底部操作区域 |
Expose
| Name | Description | Type |
|---|---|---|
| open | 打开抽屉 | () => void |
| close | 关闭抽屉 | () => void |