原文地址: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>