目录
1.通过splitpanes封装
参考文章:封装vue通用拖拽滑动分隔面板组件(Split) - 掘金
使用js库:splitpanes https://antoniandre.github.io/splitpanes/https://antoniandre.github.io/splitpanes/
使用方法:
npm i splitpanes # For Vue 3
完整代码:
<template>
<div ref="splitPane" class="split-pane" :class="props.direction" :style="{ flexDirection: direction }">
<div class="pane pane-one" :style="lengthType + ':' + paneLengthValue">
<slot name="one"></slot>
</div>
<div class="pane-trigger" :style="lengthType + ':' + triggerLengthValue" @mousedown="handleMouseDown"></div>
<div class="pane pane-two">
<slot name="two"></slot>
</div>
</div>
</template>
<script setup>
import { ref, defineProps, computed } from 'vue'
/* 属性 */
const splitPane = ref()
let paneLengthPercent = ref(50) // 区域1宽度 (%)
let triggerLength = ref(10) // 滑动器宽度 (px)
let triggerLeftOffset = ref(0) // 鼠标距滑动器左(顶)侧偏移量
const props = defineProps({
direction: {
type: String,
default: 'column'
},
//滑动限制-最小
min: {
type: Number,
default: 10
},
//滑动限制-最大
max: {
type: Number,
default: 90
},
paneLengthPercent: {
type: Number,
default: 50
},
triggerLength: {
type: Number,
default: 10
}
})
const lengthType = computed(() => {
return props.direction === 'row' ? 'width' : 'height'
})
const paneLengthValue = computed(() => {
return `calc(${paneLengthPercent.value}% - ${triggerLength.value / 2 + 'px'})`
})
const triggerLengthValue = computed(() => {
return triggerLength.value + 'px'
})
/* 方法 */
// 按下滑动器
const handleMouseDown = (e) => {
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
if (props.direction === 'row') {
triggerLeftOffset.value = e.pageX - e.srcElement.getBoundingClientRect().left
} else {
triggerLeftOffset.value = e.pageY - e.srcElement.getBoundingClientRect().top
}
}
// 按下滑动器后移动鼠标
const handleMouseMove = (e) => {
const clientRect = splitPane.value.getBoundingClientRect()
paneLengthPercent.value = 0
//方向判断
if (props.direction === 'row') {
const offset = e.pageX - clientRect.left - triggerLeftOffset.value + triggerLength.value / 2
paneLengthPercent.value = (offset / clientRect.width) * 100
} else {
const offset = e.pageY - clientRect.top - triggerLeftOffset.value + triggerLength.value / 2
paneLengthPercent.value = (offset / clientRect.height) * 100
}
//滑动限制判断
if (paneLengthPercent.value < props.min) {
paneLengthPercent.value = props.min
}
if (paneLengthPercent.value > props.max) {
paneLengthPercent.value = props.max
}
}
// 松开滑动器
const handleMouseUp = () => {
document.removeEventListener('mousemove', handleMouseMove)
}
</script>
<style scoped lang="scss">
.split-pane {
background: palegreen;
height: 100%;
display: flex;
&.row {
.pane {
height: 100%;
}
.pane-trigger {
height: 100%;
cursor: col-resize; //鼠标样式
}
}
&.column {
.pane {
width: 100%;
}
.pane-trigger {
width: 100%;
cursor: row-resize; //鼠标样式
}
}
.pane-one {
width: 50%;
background: palevioletred;
}
.pane-trigger {
background: palegoldenrod;
user-select: none;
}
.pane-two {
flex: 1;
background: turquoise;
}
}
</style>
2.通过vue-splitpane插件
参考文章:Vue中 引入使用 vue-splitpane 实现窗格的拆分、调节_明天也要努力的博客-CSDN博客_vue-splitpane