实现Area组件功能需求:初始位置居中、最大化还原、边界限制、单Panel无标题栏
This commit is contained in:
@@ -85,6 +85,8 @@ const originalPosition = ref({
|
|||||||
left: props.left,
|
left: props.left,
|
||||||
top: props.top
|
top: props.top
|
||||||
})
|
})
|
||||||
|
// 保存最大化前的位置和大小,用于还原
|
||||||
|
const maximizedFromPosition = ref(null)
|
||||||
|
|
||||||
// 拖拽相关状态
|
// 拖拽相关状态
|
||||||
const isDragging = ref(false)
|
const isDragging = ref(false)
|
||||||
@@ -167,13 +169,13 @@ const onDragMove = (e) => {
|
|||||||
let newLeft = areaStartPos.value.x + deltaX
|
let newLeft = areaStartPos.value.x + deltaX
|
||||||
let newTop = areaStartPos.value.y + deltaY
|
let newTop = areaStartPos.value.y + deltaY
|
||||||
|
|
||||||
// 如果有父容器引用,应用边界限制
|
// 确保不超出父容器边界
|
||||||
if (parentContainer.value) {
|
if (parentContainer.value) {
|
||||||
const parentRect = parentContainer.value.getBoundingClientRect()
|
const parentRect = parentContainer.value.getBoundingClientRect()
|
||||||
const areaWidth = originalPosition.value.width
|
const areaWidth = originalPosition.value.width
|
||||||
const areaHeight = originalPosition.value.height
|
const areaHeight = originalPosition.value.height
|
||||||
|
|
||||||
// 确保不超出父容器边界
|
// 严格边界检查,确保元素完全在父容器内
|
||||||
newLeft = Math.max(0, Math.min(newLeft, parentRect.width - areaWidth))
|
newLeft = Math.max(0, Math.min(newLeft, parentRect.width - areaWidth))
|
||||||
newTop = Math.max(0, Math.min(newTop, parentRect.height - areaHeight))
|
newTop = Math.max(0, Math.min(newTop, parentRect.height - areaHeight))
|
||||||
}
|
}
|
||||||
@@ -197,15 +199,22 @@ const onDragEnd = () => {
|
|||||||
const onToggleMaximize = () => {
|
const onToggleMaximize = () => {
|
||||||
const next = isMaximized.value ? '正常' : '最大化'
|
const next = isMaximized.value ? '正常' : '最大化'
|
||||||
|
|
||||||
// 如果是从正常状态切换到最大化状态,保存当前位置信息
|
|
||||||
if (!isMaximized.value) {
|
if (!isMaximized.value) {
|
||||||
// 保存当前位置和大小,用于还原
|
// 切换到最大化状态前,保存当前位置和大小
|
||||||
originalPosition.value = {
|
maximizedFromPosition.value = {
|
||||||
width: originalPosition.value.width,
|
width: originalPosition.value.width,
|
||||||
height: originalPosition.value.height,
|
height: originalPosition.value.height,
|
||||||
left: originalPosition.value.left,
|
left: originalPosition.value.left,
|
||||||
top: originalPosition.value.top
|
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
|
localState.value = next
|
||||||
@@ -214,9 +223,28 @@ const onToggleMaximize = () => {
|
|||||||
|
|
||||||
const onClose = () => emit('close')
|
const onClose = () => emit('close')
|
||||||
|
|
||||||
// 组件挂载后获取父容器引用
|
// 组件挂载后获取父容器引用并初始化位置
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
parentContainer.value = document.querySelector('.dock-layout') || window
|
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>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
:id="area.id"
|
:id="area.id"
|
||||||
:title="area.title"
|
:title="area.title"
|
||||||
v-model:WindowState="area.WindowState"
|
v-model:WindowState="area.WindowState"
|
||||||
:showTitleBar="area.showTitleBar"
|
:showTitleBar="area.panels.length !== 1"
|
||||||
:width="area.width"
|
:width="area.width"
|
||||||
:height="area.height"
|
:height="area.height"
|
||||||
:left="area.WindowState !== '最大化' ? area.x : undefined"
|
:left="area.WindowState !== '最大化' ? area.x : undefined"
|
||||||
|
|||||||
Reference in New Issue
Block a user