所需传参如下:
传入中心线左侧元素、右侧元素和外侧元素的className,实现拖拽改变左右元素的宽度
* @Props:
classNames:{
box String 外侧容器className
left String 左侧容器className
@right String 右侧容器className
}
-->
这里要确保左右和外侧的元素className唯一,也可以自己改成查找id的。
<template>
<div class="centerLine"></div>
</template>
<script>
import * as ApiCom from '@/api/common'
export default {
name: 'centerLine',
props: {
//传入的左中右三个className
classNames: {
type: Object,
default: () => {
return {}
},
},
},
data() {
return {
screenWidth: document.body.clientWidth,
leftMinWidth: 500, //左侧最小宽度
rightMinWidth: 500, //右侧最小宽度
}
},
mounted() {
this.setEvent()
window.addEventListener('centerLine', this.setWidth())
},
watch: {
screenWidth(newVal, oldVal) {
const centerLine = document.getElementsByClassName('centerLine')?.[0]
let right = document.getElementsByClassName(this.classNames.right)?.[0]
right.style.width = `${newVal - centerLine.offsetLeft}px`
},
},
methods: {
setWidth() {
this.screenWidth = document.body.clientWidth
},
/**
* @description: 设置鼠标事件
* @return Boolean
*/
setEvent() {
const { classNames, leftMinWidth, rightMinWidth } = this
let centerLine = document.getElementsByClassName('centerLine')?.[0]
let left = document.getElementsByClassName(classNames.left)?.[0]
let right = document.getElementsByClassName(classNames.right)?.[0]
let box = document.getElementsByClassName(classNames.box)?.[0]
let leftWidth
// 鼠标按下事件
centerLine.onmousedown = (e) => {
const startX = e.clientX
centerLine.left = centerLine.offsetLeft
// 鼠标拖动事件
document.onmousemove = (e) => {
const endX = e.clientX
leftWidth = centerLine.left + (endX - startX) // endx-startx移动的距离。centerLine.left+移动的距离 = 左边区域最后的宽度
const rightWidth = box.clientWidth - centerLine.offsetWidth //右边区域的宽度 = 容器宽度 - 左边区域的宽度
leftWidth < leftMinWidth && (leftWidth = leftMinWidth) // 左边区域的最小宽度
leftWidth > rightWidth - rightMinWidth &&
(leftWidth = rightWidth - rightMinWidth) //右边区域最小宽度
centerLine.style.left = leftWidth // 设置左侧区域的宽度
left.style.width = `${leftWidth}px`
right.style.width = `${box.clientWidth - leftWidth - 12}px` //12是中心线的总宽度
}
// 鼠标松开事件
document.onmouseup = (e) => {
document.onmousemove = null
document.onmouseup = null
centerLine.releaseCapture?.() //不需要继续获得鼠标消息要调用ReleaseCapture()释放
this.setDetailsWidth(leftWidth) //保存修改后的宽度
}
centerLine.setCapture?.() //指定窗口里设置鼠标捕获
return false
}
},
},
beforeDestroy() {
window.onresize = null
window.removeEventListener('centerLine', this.setWidth()) //移除监听
},
}
</script>
<style lang="stylus" scoped >
.centerLine {
height: 200px;
display: flex;
align-items: center;
cursor: col-resize;
margin: auto 5px;
border-left: 2px solid #b4b9c1;
&:hover {
height: calc(100% + 10px); // 超出左右一点点
border-left: 2px dashed #409eff;
margin: -5px 5px 0 5px;
}
}
</style>