更新DockLayout组件:清理DockIndicator和相关依赖
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
class="vs-area select-none"
|
class="vs-area select-none"
|
||||||
:class="{ 'is-maximized': isMaximized, 'is-normal': !isMaximized }"
|
:class="{ 'is-maximized': isMaximized, 'is-normal': !isMaximized }"
|
||||||
:style="areaStyle"
|
:style="areaStyle"
|
||||||
|
@dragover="handleDragOver"
|
||||||
|
@dragleave="handleDragLeave"
|
||||||
>
|
>
|
||||||
<!-- 调整大小的边框 -->
|
<!-- 调整大小的边框 -->
|
||||||
<div
|
<div
|
||||||
@@ -234,7 +236,8 @@ const props = defineProps({
|
|||||||
showTitleBar: { type: Boolean, default: true },
|
showTitleBar: { type: Boolean, default: true },
|
||||||
// 位置属性,可选
|
// 位置属性,可选
|
||||||
left: { type: Number, default: undefined },
|
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
|
return style
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['close', 'update:WindowState', 'update:position'])
|
const emit = defineEmits(['close', 'update:WindowState', 'update:position', 'dragover', 'dragleave'])
|
||||||
|
|
||||||
// 处理Panel的最大化事件
|
// 处理Panel的最大化事件
|
||||||
const onPanelMaximize = (panelId) => {
|
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) => {
|
const onDragStart = (e) => {
|
||||||
// 最大化状态下不允许拖拽
|
// 最大化状态下不允许拖拽
|
||||||
|
|||||||
@@ -1,55 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="visible" class="dock-indicator" :style="indicatorStyle">
|
<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):封装所有渐变和路径(只写一次) -->
|
<!-- 1. 定义可复用组件(symbol):封装所有渐变和路径(只写一次) -->
|
||||||
<svg width="0" height="0" viewBox="0 0 40 40" aria-hidden="true">
|
<svg width="0" height="0" viewBox="0 0 40 40" aria-hidden="true">
|
||||||
<defs>
|
<defs>
|
||||||
@@ -174,7 +125,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, watch } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
// Props定义
|
// Props定义
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -192,36 +143,9 @@ const props = defineProps({
|
|||||||
width: 0,
|
width: 0,
|
||||||
height: 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(() => {
|
const indicatorStyle = computed(() => {
|
||||||
return {
|
return {
|
||||||
@@ -234,78 +158,6 @@ const indicatorStyle = computed(() => {
|
|||||||
zIndex: 9999
|
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>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -313,87 +165,4 @@ defineExpose({
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
box-sizing: border-box;
|
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>
|
</style>
|
||||||
Reference in New Issue
Block a user