<template>
<el-drawer
modal-class="app-modal"
class="app-drawer"
v-bind="$attrs"
:direction="direction"
:model-value="visible"
:close-on-press-escape="false"
:close-on-click-modal="false"
:destroy-on-close="true"
:size="h"
:before-close="handleClose"
>
<template v-for="item in Object.keys($slots)" #[item]>
<slot :name="item"> </slot>
</template>
<template #title>
<div class="drawer-head">
{{ title }}
<div v-if="direction === 'btt'" class="drawer-icon">
<span class="cursor-move" @mousedown="onDown">
<el-icon><Sort /></el-icon>
</span>
</div>
</div>
</template>
</el-drawer>
</template>
<script lang="ts" setup>
import { PropType, ref, onMounted } from "vue";
import { Sort } from "@element-plus/icons-vue";
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
size: {
type: String,
default: "50%",
},
direction: {
type: String as PropType<"ltr" | "rtl" | "ttb" | "btt">,
default: "btt",
},
title: {
type: String,
default: "",
},
});
const darwerEle = ref<any>();
const dragStatus = ref<any>(); // 1开始 2停止
const h = ref<any>();
onMounted(() => {
h.value = props.size;
});
function onDown(e: any) {
darwerEle.value = e;
dragStatus.value = 1;
document.onmousemove = (event: any) => {
if (darwerEle.value && dragStatus.value === 1) {
const height = event.clientY;
const all = document.documentElement.clientHeight;
const limit = all * (1 - parseInt(props.size) / 100);
if (height <= limit) {
h.value = ((all - height) / all) * 100 + "%";
} else {
h.value = props.size;
}
}
};
document.onmouseup = () => {
// 松开鼠标初始化
darwerEle.value = null;
dragStatus.value = 2;
document.onmouseup = null;
document.onmousemove = null;
return false;
};
document.ondragstart = (ev) => {
ev.preventDefault();
};
document.ondragend = (ev) => {
ev.preventDefault();
};
}
const emits = defineEmits(["update:visible", "close"]);
function handleClose() {
emits("update:visible", false);
emits("close");
}
</script>
<style lang="scss">
.app-modal {
background: transparent;
}
.app-drawer {
background: url("@/assets/imgs/layout/bg-component.png") no-repeat center;
background-size: cover;
max-height: 100%;
min-height: 30%;
.el-drawer__header,
.el-drawer__body {
width: 100%;
margin: 0 auto;
@apply max-w-screen-xl;
}
&.el-drawer.ltr,
&.el-drawer.rtl {
top: 80px;
height: calc(100vh - 80px);
}
}
.drawer-head {
position: relative;
}
.drawer-icon {
position: absolute;
top: -18px;
left: 0;
right: 0;
text-align: center;
}
</style>
vue3+element-plus+ts封装可拖拽抽屉组件
最新推荐文章于 2024-08-16 00:53:06 发布