修复切换页标签后关闭面板会关闭所有面板的异常

This commit is contained in:
zqm
2026-01-13 16:56:27 +08:00
parent d0e45bd479
commit 4a14dc9158
4 changed files with 64 additions and 1 deletions

View File

@@ -86,6 +86,7 @@ const mainAreaConfig = ref({
showTitleBar: false, showTitleBar: false,
children: { children: {
type: 'TabPage', type: 'TabPage',
id: `tabPage-${Date.now()}`,
children: [] children: []
} }
}) })
@@ -286,6 +287,15 @@ const onPanelClose = (event) => {
// 3. 只移除指定的面板,不影响其他面板 // 3. 只移除指定的面板,不影响其他面板
child.children.splice(i, 1); child.children.splice(i, 1);
// 发送面板移除事件通知TabPage组件调整activeTabIndex
const tabPageId = child.id || `tabPage-${areaId}`;
eventBus.emit(EVENT_TYPES.TABPAGE_PANEL_REMOVED, {
tabPageId,
removedPanelId: panelId,
removedIndex: i,
remainingPanelCount: child.children.length
}, { componentId: 'dock-layout' });
// 4. 检查TabPage是否还有子元素 // 4. 检查TabPage是否还有子元素
// 当child.children为空数组时认为TabPage没有子元素 // 当child.children为空数组时认为TabPage没有子元素
if (child.children.length === 0) { if (child.children.length === 0) {
@@ -535,12 +545,28 @@ const onTabClose = async (data) => {
if (Array.isArray(targetTabPage.children)) { if (Array.isArray(targetTabPage.children)) {
targetTabPage.children.splice(panelIndex, 1); targetTabPage.children.splice(panelIndex, 1);
console.log(`📌 从TabPage移除Panel后剩余Panel数量: ${targetTabPage.children.length}`); console.log(`📌 从TabPage移除Panel后剩余Panel数量: ${targetTabPage.children.length}`);
// 发送Panel移除事件通知TabPage组件调整activeTabIndex
eventBus.emit(EVENT_TYPES.TABPAGE_PANEL_REMOVED, {
tabPageId,
removedPanelId: panelId,
removedIndex: panelIndex,
remainingPanelCount: targetTabPage.children.length
}, { componentId: 'dock-layout' });
} else { } else {
// 当TabPage只有一个Panel时我们将children设置为null // 当TabPage只有一个Panel时我们将children设置为null
// 这样shouldShowTabs计算属性会返回false不显示标签栏 // 这样shouldShowTabs计算属性会返回false不显示标签栏
// 但TabPage仍然存在 // 但TabPage仍然存在
targetTabPage.children = null; targetTabPage.children = null;
console.log(`📌 移除了唯一的PanelTabPage不显示标签栏`); console.log(`📌 移除了唯一的PanelTabPage不显示标签栏`);
// 发送Panel移除事件通知TabPage组件调整activeTabIndex
eventBus.emit(EVENT_TYPES.TABPAGE_PANEL_REMOVED, {
tabPageId,
removedPanelId: panelId,
removedIndex: panelIndex,
remainingPanelCount: 0
}, { componentId: 'dock-layout' });
} }
// 5. 检查TabPage是否还有子元素 // 5. 检查TabPage是否还有子元素
@@ -874,6 +900,7 @@ const addFloatingPanel = (panel) => {
// 使用children结构以兼容Render组件的渲染逻辑 // 使用children结构以兼容Render组件的渲染逻辑
children: { children: {
type: 'TabPage', type: 'TabPage',
id: `tabPage-${areaId}`,
tabPosition: ['top', 'right', 'bottom', 'left'][Math.floor(Math.random() * 4)], tabPosition: ['top', 'right', 'bottom', 'left'][Math.floor(Math.random() * 4)],
children: [ children: [
{ {

View File

@@ -133,7 +133,7 @@
<script setup> <script setup>
import { defineProps, ref, onMounted, onUnmounted, computed } from 'vue' import { defineProps, ref, onMounted, onUnmounted, computed } from 'vue'
import { emitEvent, EVENT_TYPES } from './eventBus' import { emitEvent, eventBus, EVENT_TYPES } from './eventBus'
import Render from './Render.vue' import Render from './Render.vue'
const props = defineProps({ const props = defineProps({
@@ -215,6 +215,37 @@ onMounted(() => {
setActiveTab(0) setActiveTab(0)
} }
} }
// 监听面板移除事件调整activeTabIndex
const unsubscribe = eventBus.on(EVENT_TYPES.TABPAGE_PANEL_REMOVED, (data) => {
if (data.tabPageId === props.id) {
console.log(`[TabPage:${props.id}] 收到Panel移除事件:`, data);
if (data.remainingPanelCount === 0) {
// 如果移除后没有Panel了重置activeTabIndex
activeTabIndex.value = -1;
console.log(` → 没有Panel了重置activeTabIndex为-1`);
} else if (activeTabIndex.value >= data.remainingPanelCount) {
// 如果当前激活的索引超出范围,调整为最后一个
const oldIndex = activeTabIndex.value;
activeTabIndex.value = data.remainingPanelCount - 1;
console.log(` → 激活索引${oldIndex}超出范围,调整为${activeTabIndex.value}`);
} else if (activeTabIndex.value > data.removedIndex) {
// 如果当前激活的索引在移除的索引之后需要减1
const oldIndex = activeTabIndex.value;
activeTabIndex.value -= 1;
console.log(` → 激活索引在移除索引之后,从${oldIndex}调整为${activeTabIndex.value}`);
}
// 如果当前激活的索引在移除的索引之前,不需要调整
console.log(` → 调整后的activeTabIndex: ${activeTabIndex.value}`);
}
}, { componentId: 'tabpage' });
// 保存取消订阅函数,在组件卸载时清理
onUnmounted(() => {
unsubscribe();
console.log(`[TabPage:${props.id}] 已清理Panel移除事件监听`);
});
}) })
// 关闭标签页 // 关闭标签页

View File

@@ -177,6 +177,9 @@ export const EVENT_TYPES = {
TABPAGE_DRAG_END: 'tabpage.drag.end', TABPAGE_DRAG_END: 'tabpage.drag.end',
TABPAGE_DRAG_CANCEL: 'tabpage.drag.cancel', TABPAGE_DRAG_CANCEL: 'tabpage.drag.cancel',
// 标签页面板移除事件
TABPAGE_PANEL_REMOVED: 'tabpage.panel.removed',
INDICATOR_SHOW: 'indicator.show', INDICATOR_SHOW: 'indicator.show',
INDICATOR_HIDE: 'indicator.hide', INDICATOR_HIDE: 'indicator.hide',
INDICATOR_UPDATE: 'indicator.update', INDICATOR_UPDATE: 'indicator.update',

View File

@@ -206,6 +206,8 @@ class PanelEventHandler {
panelState.closed = true panelState.closed = true
panelState.closedAt = Date.now() panelState.closedAt = Date.now()
panelState.areaId = areaId panelState.areaId = areaId
}else{
console.warn(`[PanelHandler] 未找到Panel状态: ${panelId}`)
} }
// 触发关闭事件 // 触发关闭事件