vue3+element-plus+ts封装可拖拽抽屉组件

<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>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值