实现Area标题栏拖动时显示停靠指示器功能

- 在Area.vue中添加areaDragStart、areaDragMove、areaDragEnd事件发射
- 在DockLayout.vue中添加相应的拖拽事件处理函数
- 拖动Area标题栏时现在会显示停靠指示器,类似于Tab拖动的行为
- 符合用户需求:Area内容区可以嵌套放置Area时需要显示停靠指示器
This commit is contained in:
zqm
2025-11-14 16:02:12 +08:00
parent 65dd96be0b
commit 894fb8b87c
2 changed files with 68 additions and 1 deletions

View File

@@ -215,7 +215,7 @@ const areaStyle = computed(() => {
return style
})
const emit = defineEmits(['close', 'update:WindowState', 'update:position', 'dragover', 'dragleave'])
const emit = defineEmits(['close', 'update:WindowState', 'update:position', 'dragover', 'dragleave', 'areaDragStart', 'areaDragMove', 'areaDragEnd'])
// 处理Panel的最大化事件
const onPanelMaximize = (panelId) => {
@@ -254,6 +254,15 @@ const onDragStart = (e) => {
y: originalPosition.value.top || 0
}
// 通知父组件拖拽开始
emit('areaDragStart', {
areaId: props.id,
clientX: e.clientX,
clientY: e.clientY,
startLeft: originalPosition.value.left || 0,
startTop: originalPosition.value.top || 0
})
// 添加全局事件监听
document.addEventListener('mousemove', onDragMove)
document.addEventListener('mouseup', onDragEnd)
@@ -289,12 +298,28 @@ const onDragMove = (e) => {
originalPosition.value.left = newLeft
originalPosition.value.top = newTop
// 通知父组件拖拽移动
emit('areaDragMove', {
areaId: props.id,
clientX: e.clientX,
clientY: e.clientY,
left: newLeft,
top: newTop
})
// 通知父组件位置变化
emit('update:position', { left: newLeft, top: newTop })
}
// 拖拽结束
const onDragEnd = () => {
// 通知父组件拖拽结束
emit('areaDragEnd', {
areaId: props.id,
left: originalPosition.value.left,
top: originalPosition.value.top
})
isDragging.value = false
// 移除全局事件监听
document.removeEventListener('mousemove', onDragMove)

View File

@@ -51,6 +51,9 @@
@close="onCloseFloatingArea(area.id)"
@update:position="onUpdatePosition(area.id, $event)"
@panelMaximizeSync="onPanelMaximizeSync"
@areaDragStart="onAreaDragStart(area.id, $event)"
@areaDragMove="onAreaDragMove(area.id, $event)"
@areaDragEnd="onAreaDragEnd(area.id, $event)"
>
<!-- 每个Area内渲染其包含的TabPages -->
<TabPage
@@ -445,6 +448,45 @@ const onPanelDragEnd = () => {
}
}
// Area拖拽开始
const onAreaDragStart = (areaId, event) => {
const area = floatingAreas.value.find(a => a.id === areaId)
if (!area) return
// 拖拽开始时显示指示器
showDockIndicator.value = true
// 检查主区域内是否有其他Area
checkMainContentForAreas()
// 使用dock-layout作为默认目标区域
if (dockLayoutRef.value) {
const rect = dockLayoutRef.value.getBoundingClientRect()
targetAreaRect.value = {
left: 0,
top: 0,
width: rect.width,
height: rect.height
}
// 拖拽开始时立即更新停靠区域
updateDockZoneByMousePosition(event.clientX, event.clientY)
}
}
// Area拖拽移动
const onAreaDragMove = (areaId, event) => {
// 根据鼠标位置动态更新停靠区域
updateDockZoneByMousePosition(event.clientX, event.clientY)
}
// Area拖拽结束
const onAreaDragEnd = (areaId, event) => {
// 隐藏停靠指示器
showDockIndicator.value = false
activeDockZone.value = null
}
// TabPage拖拽开始
const onTabDragStart = (areaId, event) => {
const area = floatingAreas.value.find(a => a.id === areaId)