更新DockLayout组件:清理DockIndicator和相关依赖

This commit is contained in:
zqm
2025-11-07 17:01:47 +08:00
parent f19c0aba60
commit 231afa6244
2 changed files with 17 additions and 235 deletions

View File

@@ -3,6 +3,8 @@
class="vs-area select-none"
:class="{ 'is-maximized': isMaximized, 'is-normal': !isMaximized }"
:style="areaStyle"
@dragover="handleDragOver"
@dragleave="handleDragLeave"
>
<!-- 调整大小的边框 -->
<div
@@ -234,7 +236,8 @@ const props = defineProps({
showTitleBar: { type: Boolean, default: true },
// 位置属性,可选
left: { type: Number, default: undefined },
top: { type: Number, default: undefined }
top: { type: Number, default: undefined },
draggable: { type: Boolean, default: true }
})
// 本地状态
@@ -333,7 +336,7 @@ const areaStyle = computed(() => {
return style
})
const emit = defineEmits(['close', 'update:WindowState', 'update:position'])
const emit = defineEmits(['close', 'update:WindowState', 'update:position', 'dragover', 'dragleave'])
// 处理Panel的最大化事件
const onPanelMaximize = (panelId) => {
@@ -347,6 +350,16 @@ const onPanelMaximize = (panelId) => {
}
}
// 处理拖拽悬停事件
const handleDragOver = (event) => {
emit('dragover', event, props.id)
}
// 处理拖拽离开事件
const handleDragLeave = (event) => {
emit('dragleave', event, props.id)
}
// 拖拽开始
const onDragStart = (e) => {
// 最大化状态下不允许拖拽

View File

@@ -1,55 +1,6 @@
<template>
<div v-if="visible" class="dock-indicator" :style="indicatorStyle">
<!-- 上侧停靠指示器 -->
<div v-if="activeZones.top" class="dock-zone dock-zone-top" @dragenter="onZoneEnter('top')" @dragleave="onZoneLeave('top')" @dragover.prevent>
<div class="dock-zone-indicator">
<svg width="40" height="20" viewBox="0 0 40 20" aria-hidden="true">
<rect x="0" y="0" width="40" height="20" fill="rgba(79, 114, 179, 0.3)" />
<rect x="2" y="2" width="36" height="16" fill="rgba(79, 114, 179, 0.5)" />
</svg>
</div>
</div>
<!-- 左侧停靠指示器 -->
<div v-if="activeZones.left" class="dock-zone dock-zone-left" @dragenter="onZoneEnter('left')" @dragleave="onZoneLeave('left')" @dragover.prevent>
<div class="dock-zone-indicator">
<svg width="20" height="40" viewBox="0 0 20 40" aria-hidden="true">
<rect x="0" y="0" width="20" height="40" fill="rgba(79, 114, 179, 0.3)" />
<rect x="2" y="2" width="16" height="36" fill="rgba(79, 114, 179, 0.5)" />
</svg>
</div>
</div>
<!-- 右侧停靠指示器 -->
<div v-if="activeZones.right" class="dock-zone dock-zone-right" @dragenter="onZoneEnter('right')" @dragleave="onZoneLeave('right')" @dragover.prevent>
<div class="dock-zone-indicator">
<svg width="20" height="40" viewBox="0 0 20 40" aria-hidden="true">
<rect x="0" y="0" width="20" height="40" fill="rgba(79, 114, 179, 0.3)" />
<rect x="2" y="2" width="16" height="36" fill="rgba(79, 114, 179, 0.5)" />
</svg>
</div>
</div>
<!-- 下侧停靠指示器 -->
<div v-if="activeZones.bottom" class="dock-zone dock-zone-bottom" @dragenter="onZoneEnter('bottom')" @dragleave="onZoneLeave('bottom')" @dragover.prevent>
<div class="dock-zone-indicator">
<svg width="40" height="20" viewBox="0 0 40 20" aria-hidden="true">
<rect x="0" y="0" width="40" height="20" fill="rgba(79, 114, 179, 0.3)" />
<rect x="2" y="2" width="36" height="16" fill="rgba(79, 114, 179, 0.5)" />
</svg>
</div>
</div>
<!-- 中央停靠指示器 -->
<div v-if="activeZones.center" class="dock-zone dock-zone-center" @dragenter="onZoneEnter('center')" @dragleave="onZoneLeave('center')" @dragover.prevent>
<div class="dock-zone-indicator">
<svg width="60" height="60" viewBox="0 0 60 60" aria-hidden="true">
<rect x="0" y="0" width="60" height="60" fill="rgba(79, 114, 179, 0.3)" rx="5" />
<rect x="5" y="5" width="50" height="50" fill="rgba(79, 114, 179, 0.5)" rx="3" />
</svg>
</div>
</div>
<!-- 停靠指示器已移除 -->
<!-- 1. 定义可复用组件symbol封装所有渐变和路径只写一次 -->
<svg width="0" height="0" viewBox="0 0 40 40" aria-hidden="true">
<defs>
@@ -174,7 +125,7 @@
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import { computed } from 'vue'
// Props定义
const props = defineProps({
@@ -192,36 +143,9 @@ const props = defineProps({
width: 0,
height: 0
})
},
// 鼠标位置
mousePosition: {
type: Object,
default: () => ({
x: 0,
y: 0
})
},
// 停靠区域的激活阈值
threshold: {
type: Number,
default: 30
}
})
// 定义事件
const emit = defineEmits(['zone-enter', 'zone-leave', 'zone-active'])
// 状态管理
const activeZones = ref({
top: false,
left: false,
right: false,
bottom: false,
center: false
})
const selectedZone = ref(null)
// 计算指示器的样式
const indicatorStyle = computed(() => {
return {
@@ -234,78 +158,6 @@ const indicatorStyle = computed(() => {
zIndex: 9999
}
})
// 监听鼠标位置,更新活动区域
watch([() => props.mousePosition, () => props.targetRect, () => props.threshold], () => {
if (!props.visible) return
const { x, y } = props.mousePosition
const { left, top, width, height } = props.targetRect
// 重置所有区域
activeZones.value = {
top: false,
left: false,
right: false,
bottom: false,
center: false
}
// 检查鼠标是否在目标区域内
if (x >= left && x <= left + width && y >= top && y <= top + height) {
// 检查各个停靠区域
if (y <= top + props.threshold) {
activeZones.value.top = true
} else if (y >= top + height - props.threshold) {
activeZones.value.bottom = true
} else if (x <= left + props.threshold) {
activeZones.value.left = true
} else if (x >= left + width - props.threshold) {
activeZones.value.right = true
} else {
// 如果不在边缘,检查是否在中心区域
const centerX = left + width / 2
const centerY = top + height / 2
const centerRadius = Math.min(width, height) / 4
if (Math.sqrt(Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2)) <= centerRadius) {
activeZones.value.center = true
}
}
}
}, { immediate: true, deep: true })
// 当进入某个停靠区域
const onZoneEnter = (zone) => {
selectedZone.value = zone
emit('zone-enter', zone)
emit('zone-active', zone)
}
// 当离开某个停靠区域
const onZoneLeave = (zone) => {
if (selectedZone.value === zone) {
selectedZone.value = null
emit('zone-leave', zone)
emit('zone-active', null)
}
}
// 暴露方法给父组件
defineExpose({
activeZones,
selectedZone,
reset: () => {
selectedZone.value = null
activeZones.value = {
top: false,
left: false,
right: false,
bottom: false,
center: false
}
}
})
</script>
<style scoped>
@@ -313,87 +165,4 @@ defineExpose({
position: absolute;
box-sizing: border-box;
}
.dock-zone {
position: absolute;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.2s ease;
}
.dock-zone:hover {
background-color: rgba(79, 114, 179, 0.1);
}
/* 上侧停靠区域 */
.dock-zone-top {
top: 0;
left: 0;
width: 100%;
height: 30px;
}
/* 左侧停靠区域 */
.dock-zone-left {
top: 0;
left: 0;
width: 30px;
height: 100%;
}
/* 右侧停靠区域 */
.dock-zone-right {
top: 0;
right: 0;
width: 30px;
height: 100%;
}
/* 下侧停靠区域 */
.dock-zone-bottom {
bottom: 0;
left: 0;
width: 100%;
height: 30px;
}
/* 中央停靠区域 */
.dock-zone-center {
top: 50%;
left: 50%;
width: 60px;
height: 60px;
transform: translate(-50%, -50%);
border-radius: 50%;
}
.dock-zone-indicator {
display: flex;
align-items: center;
justify-content: center;
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% {
opacity: 0.7;
}
50% {
opacity: 1;
}
100% {
opacity: 0.7;
}
}
/* 活动状态的样式 */
.dock-zone.active {
background-color: rgba(79, 114, 179, 0.2);
}
.dock-zone.active .dock-zone-indicator svg rect {
fill: rgba(79, 114, 179, 0.8);
}
</style>