feat: The dividing line in the directory section can be dragged and dropped

This commit is contained in:
wangdan-fit2cloud 2025-11-11 15:53:54 +08:00 committed by CaptainB
parent 2aa2d71a1a
commit 7468bfd43f
4 changed files with 77 additions and 15 deletions

View File

@ -1,6 +1,9 @@
<template>
<div class="layout-container flex h-full">
<div :class="`layout-container__left border-r ${isCollapse ? 'hidden' : ''}`">
<div
:class="`layout-container__left border-r ${isCollapse ? 'hidden' : ''}`"
:style="{ width: isCollapse ? 0 : `${leftWidth}px` }"
>
<div class="layout-container__left_content">
<slot name="left"></slot>
</div>
@ -17,6 +20,12 @@
:icon="isCollapse ? 'ArrowRightBold' : 'ArrowLeftBold'"
/>
</el-tooltip>
<div
v-if="props.resizable"
class="splitter-bar-line"
:class="isResizing ? 'hover' : ''"
@mousedown="onSplitterMouseDown"
></div>
</div>
<div class="layout-container__right">
<slot></slot>
@ -25,20 +34,56 @@
</template>
<script setup lang="ts">
import { computed, useSlots, ref } from 'vue'
import { onUnmounted, ref } from 'vue'
defineOptions({ name: 'LayoutContainer' })
const slots = useSlots()
const props = defineProps({
header: String || null,
backTo: String,
showCollapse: Boolean,
resizable: Boolean,
minLeftWidth: {
type: Number,
default: 240,
},
maxLeftWidth: {
type: Number,
default: 400,
},
})
const isCollapse = ref(false)
const leftWidth = ref(props.minLeftWidth)
const isResizing = ref(false)
const showBack = computed(() => {
const { backTo } = props
return backTo
const onSplitterMouseDown = (e: MouseEvent) => {
if (!props.resizable) return
e.preventDefault()
isResizing.value = true
document.body.style.userSelect = 'none'
const startX = e.clientX
const startWidth = leftWidth.value
const onMouseMove = (moveEvent: MouseEvent) => {
if (!isResizing.value) return
const deltaX = moveEvent.clientX - startX
let newWidth = startWidth + deltaX
//
newWidth = Math.max(props.minLeftWidth, Math.min(props.maxLeftWidth, newWidth))
leftWidth.value = newWidth
}
const onMouseUp = () => {
isResizing.value = false
document.body.style.userSelect = ''
document.removeEventListener('mousemove', onMouseMove)
document.removeEventListener('mouseup', onMouseUp)
}
document.addEventListener('mousemove', onMouseMove)
document.addEventListener('mouseup', onMouseUp)
}
onUnmounted(() => {
document.removeEventListener('mousemove', () => {})
document.removeEventListener('mouseup', () => {})
})
</script>
@ -47,17 +92,34 @@ const showBack = computed(() => {
&__left {
position: relative;
box-sizing: border-box;
transition: width 0.28s;
// transition: width 0.28s;
width: var(--sidebar-width);
min-width: var(--sidebar-width);
box-sizing: border-box;
.splitter-bar-line {
z-index: 1;
position: absolute;
top: 0;
right: 0;
cursor: col-resize;
width: 4px;
height: 100%;
&.hover:after {
width: 1px;
height: 100%;
content: '';
z-index: 2;
position: absolute;
right: -1px;
top: 0;
background: var(--el-color-primary);
}
}
.collapse {
position: absolute;
top: 36px;
right: -12px;
box-shadow: 0px 5px 10px 0px var(--app-text-color-light-1);
z-index: 1;
z-index: 2;
}
.layout-container__left_content {

View File

@ -1,5 +1,5 @@
<template>
<LayoutContainer showCollapse class="application-manage">
<LayoutContainer showCollapse resizable class="application-manage">
<template #left>
<h4 class="p-12-16 pb-0 mt-12">{{ $t('views.application.title') }}</h4>

View File

@ -1,5 +1,5 @@
<template>
<LayoutContainer showCollapse class="knowledge-manage">
<LayoutContainer showCollapse resizable class="knowledge-manage">
<template #left>
<h4 class="p-12-16 pb-0 mt-12">{{ $t('views.knowledge.title') }}</h4>

View File

@ -1,5 +1,5 @@
<template>
<LayoutContainer showCollapse class="tool-manage">
<LayoutContainer showCollapse resizable class="tool-manage">
<template #left>
<h4 class="p-12-16 pb-0 mt-12">{{ $t('views.tool.title') }}</h4>