Vue拖拽边框的进一步实现

原文地址:https://blog.csdn.net/weixin_45337695/article/details/113337753

对于一组拖拽,应该分为左侧,拖拽框,右侧三部分。(或者是上测,拖拽框,下侧三部分)函数的参数为:

对于水平的拖拽框,第一个参数是上侧的元素,第二个拖拽框是下侧的元素,第三四个参数是上下最小的距离,第四个参数是拖拽框本身,第五个参数是是否是水平的,为true。

对于垂直的拖拽框,第一个参数是左侧的元素,第二个是右侧的元素,第三四个是左右最小的距离,第四给是拖拽框本身,第五个是是否水平,为false

//拖动边框生成函数
const createResizeHandler = (
    leftOrTop: any,
    rightOrBottom: any,
    maxLeft: number,
    maxRight: number,
    resize: any,
    isX: boolean
  ) => {
    
    
    return function (e: any) {
    
    
      resize.value.style.background = "#818181"; // 颜色改变提醒
      const startX = isX ? e.clientY : e.clientX;
      if (isX) {
    
    
        resize.value.top = leftOrTop.value.offsetHeight;
      } else {
    
    
        resize.value.left = resize.value.offsetLeft;
      }
      let lastTotalLen = isX
        ? leftOrTop.value.clientHeight + rightOrBottom.value.clientHeight
        : leftOrTop.value.clientWidth + rightOrBottom.value.clientWidth;
      // let lastTotalLen = container.value.clientWidth
      // 鼠标拖动事件
      document.onmousemove = function (e: any) {
    
    
        const endX = isX ? e.clientY : e.clientX;
        // (endX-startX)=移动的距离。resize[i].left+移动的距离=左侧最终的高度
        let moveLen = isX
          ? resize.value.top + (endX - startX)
          : resize.value.left + (endX - startX);
        // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
        const maxT = isX
          ? lastTotalLen - resize.value.offsetHeight
          : lastTotalLen - resize.value.offsetWidth;
        // left最小宽度度为30px
        moveLen = moveLen < maxLeft ? maxLeft : moveLen;
        moveLen = moveLen + maxRight > maxT ? maxT - maxRight : moveLen;
        if (isX) {
    
    
          resize.value.style.height = moveLen; // 设置top区域的高度
          leftOrTop.value.style.height = moveLen + "px";
          rightOrBottom.value.style.height = `${
      
      lastTotalLen - moveLen}px`;
        } else {
    
    
          resize.value.style.left = moveLen; // 设置left区域的宽度
          leftOrTop.value.style.width = `${
      
      moveLen}px`;
          rightOrBottom.value.style.width = `${
      
      lastTotalLen - moveLen}px`;
        }
      };
      // 鼠标松开事件
      document.onmouseup = function (evt) {
    
    
        // 颜色恢复
        resize.value.style.background = "#C0C4CC";
        document.onmousemove = null;
        document.onmouseup = null;
        resize.value.releaseCapture && resize.value.releaseCapture(); // 当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
      };
      resize.value.setCapture && resize.value.setCapture(); // 该函数在属于当前线程的指定窗口里设置鼠标捕获
      return false;
    };
  };

下面是如何使用的例子:

<template>
  <div class="t" ref="t">
    <div class="tl" ref="tl">
    </div>
    <div class="y-resize" ref="resizey"></div>
    <div class="tr" ref="tr">
    </div>
  </div>
  <div class="x-resize" ref="resizex"></div>
  <div class="b" ref="b"></div>
</template>

<script setup lang="ts">
import {
      
       Ref, ref, onMounted } from "vue";
const resizey = ref()
const resizex = ref()
const t = ref()
const b = ref()
const tl = ref()
const tr = ref()
const columnList: Ref<{
      
       prop: string; label: string }[]> = ref([]);

onMounted(() => {
      
      
  //注册移动位置的函数
  resizey.value.onmousedown = createResizeHandler(
    tl,
    tr,
    30,
    30,
    resizey,
    false
  );
  resizex.value.onmousedown = createResizeHandler(
    t,
    b,
    30,
    30,
    resizex,
    true
  );
});
</script>

<style lang="scss">
$resize-width: 2px;

.t {
      
      
  height: calc(50% - $resize-width);
  width: 100%;

  .tl {
      
      
    height: 100%;
    width: calc(20% - $resize-width);
    float: left;
  }

  .y-resize {
      
      
    height: 100%;
    width: calc($resize-width - 1px);
    border-right: 1px solid var(--el-border-color);
    float: left;
    cursor: w-resize;
  }

  .tr {
      
      
    height: 100%;
    width: 80%;
    float: left;
  }
}

.x-resize {
      
      
  height: calc($resize-width - 1px);
  width: 100%;
  border-top: 1px solid var(--el-border-color);
  cursor: s-resize;
  position: relative;
}

.b {
      
      
  height: 50%;
  width: 100%;
}
</style>

猜你喜欢

转载自blog.csdn.net/HGGshiwo/article/details/127799590