### 主要修复内容

1. 事件监听器泄漏 :修复了事件监听器泄漏问题,确保所有监听器都能被正确清理
2. 组件生命周期管理 :为所有组件添加了onUnmounted钩子,确保资源能被正确清理
3. props大小写问题 :修复了props名称大小写不匹配问题
4. 延迟初始化 :将事件管理器的初始化从立即初始化改为延迟初始化,提高性能
5. flexbox布局修复 :修复了flexbox布局问题,确保组件能正确显示
6. 代码结构优化 :简化了代码结构,提高了可维护性
这些修改解决了事件监听器泄漏、组件生命周期管理和props传递等问题,提高了代码的质量和可维护性。
This commit is contained in:
zqm
2025-12-04 14:58:41 +08:00
parent e9ef33bd62
commit e96e3018ed
8 changed files with 414 additions and 226 deletions

View File

@@ -132,7 +132,7 @@
</template>
<script setup>
import { defineProps, computed, defineEmits, ref, onMounted, watch, defineExpose } from 'vue'
import { defineProps, computed, defineEmits, ref, onMounted, onUnmounted, watch, defineExpose } from 'vue'
import TabPage from './TabPage.vue'
import Panel from './Panel.vue'
import { zIndexManager, Z_INDEX_LAYERS } from './dockLayers.js'
@@ -142,7 +142,7 @@ const props = defineProps({
title: { type: String, default: '面板区' },
resizable: { type: Boolean, default: true },
// 初始状态(支持中文值)
WindowState: { type: String, default: '正常' },
windowState: { type: String, default: '正常' },
// 默认尺寸
width: { type: Number, default: 300 },
height: { type: Number, default: 250 },
@@ -155,7 +155,7 @@ const props = defineProps({
})
// 本地状态
const localState = ref(props.WindowState)
const localState = ref(props.windowState)
// 保存原始位置和大小信息
const originalPosition = ref({
width: props.width,
@@ -200,8 +200,8 @@ watch(() => props.top, (newTop) => {
}
}, { immediate: true })
// 监听WindowState变化同步更新localState
watch(() => props.WindowState, (newState) => {
// 监听windowState变化同步更新localState
watch(() => props.windowState, (newState) => {
if (newState !== localState.value) {
localState.value = newState
@@ -568,6 +568,18 @@ onMounted(() => {
}
})
// 组件卸载时清理全局事件监听器
onUnmounted(() => {
// 清理拖拽相关的全局事件监听器
document.removeEventListener('mousemove', onDragMove)
document.removeEventListener('mouseup', onDragEnd)
// 清理调整大小相关的全局事件监听器
document.removeEventListener('mousemove', onResizeMove)
document.removeEventListener('mouseup', onResizeEnd)
document.removeEventListener('mouseleave', onResizeEnd)
})
// 处理Area合并内容
@@ -589,17 +601,15 @@ const mergeAreaContent = (sourceArea) => {
// 处理源Area的所有tabPages支持两种模式tabPages和children
let tabPagesData = []
if (sourceArea.tabPages && Array.isArray(sourceArea.tabPages)) {
// 模式1直接tabPages结构
tabPagesData = sourceArea.tabPages
} else if (sourceArea.children && Array.isArray(sourceArea.children)) {
// 模式2children结构需要遍历查找TabPage类型
for (const child of sourceArea.children) {
if (child.type === 'TabPage' && child.children && child.children.type === 'Panel') {
if (sourceArea.children) {
// 统一处理children结构
const childrenArray = Array.isArray(sourceArea.children) ? sourceArea.children : [sourceArea.children]
for (const child of childrenArray) {
if (child.type === 'TabPage' && child.children) {
tabPagesData.push({
id: child.id,
title: child.title,
panels: child.children.items || []
panels: Array.isArray(child.children) ? child.children : (child.children.type === 'Panel' ? [child.children] : [])
})
}
}
@@ -655,20 +665,18 @@ const mergeAreaContent = (sourceArea) => {
return false
}
// 处理源Area的所有tabPages支持两种模式tabPages和children
// 处理源Area的所有children统一使用children结构
let tabPagesData = []
if (sourceArea.tabPages && Array.isArray(sourceArea.tabPages)) {
// 模式1直接tabPages结构
tabPagesData = sourceArea.tabPages
} else if (sourceArea.children && Array.isArray(sourceArea.children)) {
// 模式2children结构需要遍历查找TabPage类型
for (const child of sourceArea.children) {
if (child.type === 'TabPage' && child.children && child.children.type === 'Panel') {
if (sourceArea.children) {
// 统一处理children结构
const childrenArray = Array.isArray(sourceArea.children) ? sourceArea.children : [sourceArea.children]
for (const child of childrenArray) {
if (child.type === 'TabPage' && child.children) {
tabPagesData.push({
id: child.id,
title: child.title,
panels: child.children.items || []
panels: Array.isArray(child.children) ? child.children : (child.children.type === 'Panel' ? [child.children] : [])
})
}
}