Drawer 抽屉
像素风格的侧边面板,从屏幕边缘滑入。
| 名称 | 分类 | 说明 | 类型 | 默认值 |
|---|---|---|---|---|
showOverlay | 风格 | 是否显示遮罩层 | boolean | true |
size | 尺寸 | 抽屉宽度 | string | '300px' |
v-model | 状态 | 是否打开抽屉 | boolean | false |
placement | 行为 | 抽屉弹出位置 | 'left' | 'right' | 'left' |
lockScroll | 行为 | 打开时是否锁定页面滚动 | boolean | true |
closeOnClickOverlay | 行为 | 点击遮罩层是否关闭 | boolean | true |
closeOnEsc | 行为 | 按 ESC 键是否关闭 | boolean | true |
title | 内容 | 抽屉标题 | string | — |
update:modelValue | 事件 | 打开/关闭状态改变时触发 | (value: boolean) => void | — |
open | 事件 | 抽屉打开时触发 | () => void | — |
close | 事件 | 抽屉关闭时触发 | () => void | — |
default | 插槽 | 主页面内容 | — | |
sidebar | 插槽 | 抽屉侧边栏内容 | — | |
open | 暴露 | 打开抽屉 | () => void | — |
close | 暴露 | 关闭抽屉 | () => void | — |
toggle | 暴露 | 切换抽屉打开/关闭 | () => void | — |
基础用法
使用 v-model 控制抽屉的打开/关闭状态。内容放在 sidebar 插槽中。
<template>
<div>
<px-button @click="open = true">Open Drawer</px-button>
<px-drawer v-model="open">
<p>Main page content</p>
<template #sidebar>
<p>Sidebar content goes here.</p>
</template>
</px-drawer>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const open = ref(false);
</script>弹出位置
使用 placement 设置抽屉从左侧或右侧滑入。
<template>
<div class="demo-drawer">
<px-button @click="leftOpen = true">Left (default)</px-button>
<px-button @click="rightOpen = true">Right</px-button>
<px-drawer v-model="leftOpen" placement="left">
<template #sidebar>
<p>Left sidebar content</p>
</template>
</px-drawer>
<px-drawer v-model="rightOpen" placement="right">
<template #sidebar>
<p>Right sidebar content</p>
</template>
</px-drawer>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const leftOpen = ref(false);
const rightOpen = ref(false);
</script>
<style scoped>
.demo-drawer {
display: flex;
gap: 12px;
}
</style>自定义尺寸
使用 size 设置抽屉宽度,接受任何 CSS 宽度值。
<template>
<div class="demo-drawer">
<px-button @click="open200 = true">200px</px-button>
<px-button @click="open50 = true">50%</px-button>
<px-drawer v-model="open200" size="200px">
<template #sidebar>
<p>Narrow drawer (200px)</p>
</template>
</px-drawer>
<px-drawer v-model="open50" size="50%">
<template #sidebar>
<p>Wide drawer (50%)</p>
</template>
</px-drawer>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const open200 = ref(false);
const open50 = ref(false);
</script>
<style scoped>
.demo-drawer {
display: flex;
gap: 12px;
}
</style>遮罩层
通过 show-overlay 和 close-on-click-overlay 控制背景遮罩层。
<template>
<div class="demo-drawer">
<px-button @click="withOverlay = true">With Overlay</px-button>
<px-button @click="noOverlay = true">No Overlay</px-button>
<px-button @click="noClose = true">No Close on Overlay</px-button>
<px-drawer v-model="withOverlay">
<template #sidebar>
<p>Click overlay to close</p>
</template>
</px-drawer>
<px-drawer v-model="noOverlay" :show-overlay="false">
<template #sidebar>
<p>No overlay background</p>
<px-button @click="noOverlay = false">Close</px-button>
</template>
</px-drawer>
<px-drawer v-model="noClose" :close-on-click-overlay="false">
<template #sidebar>
<p>Overlay click won't close</p>
<px-button @click="noClose = false">Close</px-button>
</template>
</px-drawer>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const withOverlay = ref(false);
const noOverlay = ref(false);
const noClose = ref(false);
</script>
<style scoped>
.demo-drawer {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
</style>标题
使用 title 属性渲染带有像素虚线分隔符的标题栏。
<template>
<div>
<px-button @click="open = true">Drawer with Title</px-button>
<px-drawer v-model="open" title="Settings">
<template #sidebar>
<p>The header shows a pixel-dashed divider below the title.</p>
</template>
</px-drawer>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const open = ref(false);
</script>禁用 ESC 关闭
设置 close-on-esc 为 false 以禁止按 ESC 键关闭抽屉。
<template>
<div>
<px-button @click="open = true">Escape Disabled</px-button>
<px-drawer v-model="open" :close-on-esc="false">
<template #sidebar>
<p>Press Escape — nothing happens.</p>
<px-button @click="open = false">Close Manually</px-button>
</template>
</px-drawer>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const open = ref(false);
</script>