实现Area组件功能需求:初始位置居中、最大化还原、边界限制、单Panel无标题栏

This commit is contained in:
zqm
2025-11-04 11:02:06 +08:00
parent d0ce4380f5
commit 8ec95d63f5
2 changed files with 35 additions and 7 deletions

View File

@@ -85,6 +85,8 @@ const originalPosition = ref({
left: props.left,
top: props.top
})
// 保存最大化前的位置和大小,用于还原
const maximizedFromPosition = ref(null)
// 拖拽相关状态
const isDragging = ref(false)
@@ -167,13 +169,13 @@ const onDragMove = (e) => {
let newLeft = areaStartPos.value.x + deltaX
let newTop = areaStartPos.value.y + deltaY
// 如果有父容器引用,应用边界限制
// 确保不超出父容器边界
if (parentContainer.value) {
const parentRect = parentContainer.value.getBoundingClientRect()
const areaWidth = originalPosition.value.width
const areaHeight = originalPosition.value.height
// 确保不超出父容器边界
// 严格边界检查,确保元素完全在父容器
newLeft = Math.max(0, Math.min(newLeft, parentRect.width - areaWidth))
newTop = Math.max(0, Math.min(newTop, parentRect.height - areaHeight))
}
@@ -197,15 +199,22 @@ const onDragEnd = () => {
const onToggleMaximize = () => {
const next = isMaximized.value ? '正常' : '最大化'
// 如果是从正常状态切换到最大化状态,保存当前位置信息
if (!isMaximized.value) {
// 保存当前位置和大小,用于还原
originalPosition.value = {
// 切换到最大化状态前,保存当前位置和大小
maximizedFromPosition.value = {
width: originalPosition.value.width,
height: originalPosition.value.height,
left: originalPosition.value.left,
top: originalPosition.value.top
}
} else if (maximizedFromPosition.value) {
// 从最大化状态还原时,恢复到保存的位置和大小
originalPosition.value = { ...maximizedFromPosition.value }
// 通知父组件位置变化
emit('update:position', {
left: originalPosition.value.left,
top: originalPosition.value.top
})
}
localState.value = next
@@ -214,9 +223,28 @@ const onToggleMaximize = () => {
const onClose = () => emit('close')
// 组件挂载后获取父容器引用
// 组件挂载后获取父容器引用并初始化位置
onMounted(() => {
parentContainer.value = document.querySelector('.dock-layout') || window
// 如果没有指定left或top自动居中定位
if (originalPosition.value.left === undefined || originalPosition.value.top === undefined) {
if (parentContainer.value && parentContainer.value !== window) {
const parentRect = parentContainer.value.getBoundingClientRect()
const areaWidth = originalPosition.value.width
const areaHeight = originalPosition.value.height
// 计算居中位置
originalPosition.value.left = Math.floor((parentRect.width - areaWidth) / 2)
originalPosition.value.top = Math.floor((parentRect.height - areaHeight) / 2)
// 通知父组件位置变化
emit('update:position', {
left: originalPosition.value.left,
top: originalPosition.value.top
})
}
}
})
</script>

View File

@@ -7,7 +7,7 @@
:id="area.id"
:title="area.title"
v-model:WindowState="area.WindowState"
:showTitleBar="area.showTitleBar"
:showTitleBar="area.panels.length !== 1"
:width="area.width"
:height="area.height"
:left="area.WindowState !== '最大化' ? area.x : undefined"