Front end - encapsulating vue universal drag and drop sliding partition panel component (Split)

Table of contents

 

1. Encapsulation via splitpanes


1. Encapsulation via splitpanes

Reference article: Encapsulate vue general drag and drop sliding partition panel component (Split) - Nuggets

Use the js library: splitpanes   https://antoniandre.github.io/splitpanes/ https://antoniandre.github.io/splitpanes/

Instructions:

npm i splitpanes # For Vue 3

Full code:

<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. Through the vue-splitpane plugin

Reference article: Vue introduces the use of vue-splitpane to realize the splitting and adjustment of panes

3. Through the Vue-Split-Panel plugin

Reference article: vue-split-panel - npm 

Guess you like

Origin blog.csdn.net/helloyangkl/article/details/128490436