Skip to content
On this page

Drawer 抽屉

屏幕边缘滑出的浮层面板。

基础用法

通过 v-model 双向绑定控制抽屉显示与隐藏的状态。设置direction属性,控制抽屉展开方向。组件内部的默认插槽接受用户自定义的内容。

<>
<template>
    <div>
        <kl-button @click="rtl = true">right to left</kl-button>
        <kl-button @click="ltr = true">left to right</kl-button>
        <kl-button @click="ttb = true">top to bottom</kl-button>
        <kl-button @click="btt = true">bottom to top</kl-button>

        <kl-drawer v-model="rtl" direction="rtl">
            <div class="header">
                <button @click="rtl = false"><KlOtherError /></button>
                <h3>Basic Drawer</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
        <kl-drawer v-model="ltr" direction="ltr">
            <div class="header">
                <button @click="ltr = false"><KlOtherError /></button>
                <h3>Basic Drawer</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
        <kl-drawer v-model="ttb" direction="ttb">
            <div class="header">
                <button @click="ttb = false"><KlOtherError /></button>
                <h3>Basic Drawer</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
        <kl-drawer v-model="btt" direction="btt">
            <div class="header">
                <button @click="btt = false"><KlOtherError /></button>
                <h3>Basic Drawer</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
const rtl = ref(false)
const ltr = ref(false)
const ttb = ref(false)
const btt = ref(false)
</script>

<style lang="scss" scoped>
.header {
    display: flex;
    padding: 16px 24px;
    border-bottom: 1px solid #ddd;

    h3 {
        white-space: nowrap;
        margin: 0 0 0 10px;
        padding: 0;
    }
}

.content {
    padding: 16px 24px;

    p {
        white-space: nowrap;
    }
}
</style>

抽屉尺寸

设置size属性,自定义抽屉尺寸。若传递size为数值类型,则单位为 px,同时支持传入百分比字符串。默认为 30%

<>
<template>
    <div>
        <kl-button @click="pt20 = true">20%</kl-button>
        <kl-button @click="pt30 = true">30%</kl-button>
        <kl-button @click="px200 = true">200px</kl-button>
        <kl-button @click="px300 = true">300px</kl-button>

        <kl-drawer v-model="pt20" size="20%">
            <div class="header">
                <button @click="pt20 = false"><KlOtherError /></button>
                <h3>Drawer Size</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
        <kl-drawer v-model="pt30" size="30%">
            <div class="header">
                <button @click="pt30 = false"><KlOtherError /></button>
                <h3>Drawer Size</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
        <kl-drawer v-model="px200" :size="200">
            <div class="header">
                <button @click="px200 = false"><KlOtherError /></button>
                <h3>Drawer Size</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
        <kl-drawer v-model="px300" :size="300">
            <div class="header">
                <button @click="px300 = false"><KlOtherError /></button>
                <h3>Drawer Size</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
const pt20 = ref(false)
const pt30 = ref(false)
const px200 = ref(false)
const px300 = ref(false)
</script>

<style lang="scss" scoped>
.header {
    display: flex;
    padding: 16px 24px;
    border-bottom: 1px solid #ddd;

    h3 {
        white-space: nowrap;
        margin: 0 0 0 10px;
        padding: 0;
    }
}

.content {
    padding: 16px 24px;

    p {
        white-space: nowrap;
    }
}
</style>

设置遮罩层 z-index

通过z-index属性,你可以改变遮罩层的层级。注意:抽屉层级 = 遮罩层层级 + 1。例如:如果z-index = 299,那么,遮罩层层级 = 299,抽屉层级 = 300。默认值为 1000

z-index: 300
<>
<template>
    <div>
        <div class="box">z-index: 300</div>
        <kl-button @click="drawer299 = true">z-index: 299</kl-button>
        <kl-button @click="drawer301 = true">z-index: 301</kl-button>

        <kl-drawer v-model="drawer299" :z-index="299">
            <div class="header">
                <button @click="drawer299 = false"><KlOtherError /></button>
                <h3>Drawer Tier</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
        <kl-drawer v-model="drawer301" :z-index="301">
            <div class="header">
                <button @click="drawer301 = false"><KlOtherError /></button>
                <h3>Drawer Tier</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
const drawer299 = ref(false)
const drawer301 = ref(false)
</script>

<style lang="scss" scoped>
.box {
    position: relative;
    box-sizing: border-box;
    width: 120px;
    height: 120px;
    margin: 10px;
    padding: 10px;
    background-color: #67c23a;
    color: #fff;
    z-index: 300;
}
.header {
    display: flex;
    padding: 16px 24px;
    border-bottom: 1px solid #ddd;

    h3 {
        white-space: nowrap;
        margin: 0 0 0 10px;
        padding: 0;
    }
}

.content {
    padding: 16px 24px;

    p {
        white-space: nowrap;
    }
}
</style>

是否锁定滚动条

通过设置lock-scroll属性,根据自己的需求决定是否锁定滚动条。若锁定滚动条,需要自行处理滚动条在显示与隐藏之间切换导致的页面抖动的问题。默认为true

<>
<template>
    <div>
        <kl-button @click="lock = true">锁定滚动条</kl-button>
        <kl-button @click="unlock = true">不锁定滚动条</kl-button>

        <kl-drawer v-model="lock" :lock-scroll="true">
            <div class="header">
                <button @click="lock = false"><KlOtherError /></button>
                <h3>Lock Scroll</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
        <kl-drawer v-model="unlock" :lock-scroll="false">
            <div class="header">
                <button @click="unlock = false"><KlOtherError /></button>
                <h3>Unlock Scroll</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
    </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
const lock = ref(false)
const unlock = ref(false)
</script>

<style lang="scss" scoped>
.header {
    display: flex;
    padding: 16px 24px;
    border-bottom: 1px solid #ddd;

    h3 {
        white-space: nowrap;
        margin: 0 0 0 10px;
        padding: 0;
    }
}

.content {
    padding: 16px 24px;

    p {
        white-space: nowrap;
    }
}
</style>

自定义遮罩层与抽屉样式

通过设置modal-classdrawer-class属性,你可以自定义遮罩层和抽屉的样式。

注意:想要使自定义类名生效,你需要使用:deep深度选择器

<>
<template>
    <div>
        <kl-button @click="drawer = true">自定义样式</kl-button>

        <kl-drawer v-model="drawer" modal-class="modalClass" drawer-class="drawerClass">
            <div class="header">
                <button @click="drawer = false"><KlOtherError /></button>
                <h3>Custom Class</h3>
            </div>
            <div class="content">
                <p>Some contents...</p>
                <p>Some contents...</p>
                <p>Some contents...</p>
            </div>
        </kl-drawer>
    </div>
</template>

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

<style lang="scss" scoped>
:deep(.modalClass) {
    background-color: rgba(255, 0, 0, 0.4);
}

:deep(.drawerClass) {
    background-color: #000;
    color: #fff;
}

.header {
    display: flex;
    padding: 16px 24px;
    border-bottom: 1px solid #ddd;

    h3 {
        white-space: nowrap;
        margin: 0 0 0 10px;
        padding: 0;
    }
}

.content {
    padding: 16px 24px;

    p {
        white-space: nowrap;
    }
}
</style>

API

属性

名称描述类型默认值必填
model-value / v-model是否显示抽屉boolean
size抽屉窗体的大小, 当使用 number 类型时, 以像素为单位, 当使用 string 类型时, 请传入 x%number/string'30%'
direction抽屉打开的方向rtl / ltr / ttb / bttrtl
modal是否需要遮罩层booleantrue
lock-scroll是否在抽屉出现时将 body 滚动锁定booleantrue
modal-class遮罩层的自定义类名string
drawer-class抽屉的自定义类名string
close-esc是否可以通过按下 ESC 关闭抽屉booleantrue
z-index设置遮罩层的z-index抽屉的z-index = 遮罩层的z-index + 1number1000

插槽

名称描述
default抽屉的内容

Released under the MIT License.