Files
JoyD/AutoRobot/Windows/Robot/Web/src/DockLayout

DockLayout 组件说明

本文档描述在 src/DockLayout/ 目录下将实现的停靠布局组件的目标、核心概念与数据结构约定,用于指导后续组件开发与联调。

目标概述

  • 提供 IDE/工作台类的停靠布局能力:支持上/下/左/右/中心五个面板区。
  • 每个面板区内部以 TabGroup 组织多个子面板(标签页),支持切换、关闭、最小化、浮动等扩展。
  • 建立面板区之间的“大小影响关系”,通过受影响/被影响/待更新三类列表配合队列批处理,保证尺寸与边界在增删、折叠、拖拽后稳定更新。

核心概念

  • 面板区Area指 Top/Bottom/Left/Right/Center 五个区域之一,是 DockLayout 的一级容器。
  • 子面板区SubArea面板区内部承载 TabGroup 的容器,负责布局与滚动等;一个面板区至少包含一个子面板区。
  • 子面板Panel以标签页形式存在的具体内容面板如“解决方案”、“属性”、“终端”、“编辑器”等。
  • TabGroup负责管理同一面板区内的多个子面板标签包含新增、关闭、激活等行为所有面板区均以 TabGroup 作为统一的内容组织方式。

面板区与列表约定

每个面板区都维护三类列表,用于描述与调度尺寸更新:

  • 受影响列表influence本面板区会影响到的其他面板区集合。
  • 被影响列表influencedBy会影响到本面板区的其他面板区集合。
  • 待更新列表pendingUpdates当本区状态变化新增/删除/折叠/展开/拖拽)后,入队待批处理的面板区集合。

这三类列表的存在旨在:

  • 明确依赖方向,避免双向更新导致的循环与遗漏。
  • 通过队列式批处理,多次局部变更合并为一次稳定的全局尺寸更新过程。

数据结构草案

以下为建议的数据结构,具体实现时可与现有 storedockPanelStore.js)对齐。

// 面板区枚举
export type PanelPosition = 'left' | 'right' | 'top' | 'bottom' | 'center';

// 影响关系项
export interface InfluenceEntry {
  position: PanelPosition; // 目标面板区位置
  influence: boolean;      // 是否产生影响(用于过滤/开关)
}

// 子面板(标签页)
export interface Panel {
  id: string;
  title: string;
  icon?: string;
  content?: unknown; // 组件或渲染函数引用
  collapsed?: boolean;
}

// 子面板区TabGroup 容器)
export interface SubArea {
  id: string;
  tabGroupId: string; // 绑定的 TabGroup 标识
  panels: Panel[];    // 标签页集合
}

// 面板区(一级容器)
export interface PanelArea {
  position: PanelPosition;
  subAreas: SubArea[];         // 一个或多个子面板区
  activeTabIndex?: number;     // 当前激活标签索引
  influence: InfluenceEntry[]; // 受影响列表
  influencedBy: InfluenceEntry[]; // 被影响列表
  pendingUpdates: Set<PanelPosition>; // 待更新列表(去重队列)

  // 尺寸与边界(用于绝对定位计算)
  x: number;
  y: number;
  width: number;
  height: number;

  // 面板内比例(按区维度)
  widthRatios?: number[];
  heightRatios?: number[];
}

// DockLayout 根状态
export interface PanelMeta {
  id: string;
  title: string;
  icon?: string;
  component?: unknown; // 非 DOM 实例的渲染引用或组件名
  initialPosition?: PanelPosition;
  tags?: string[];
  flags?: { collapsed?: boolean; floating?: boolean };
}

export interface DockLayoutState {
  areas: Record<PanelPosition, PanelArea>;
  allPanels: Record<string, PanelMeta>; // 全局面板列表(非 DOM 实例)
}

全局面板列表allPanels

  • 定义:全局面板列表 allPanels: Record<string, PanelMeta>,仅保存子面板元数据(非 DOM 实例)。
  • 作用:单一事实来源、去重与索引、跨区域移动一致性、持久化/导入导出、快速检索。
  • 基本 API约定registerPanel(meta), unregisterPanel(panelId), getPanelById(panelId), listPanels(), updatePanelMeta(panelId, patch)
  • 与 TabGroup/面板区协作:面板区仅保存面板 id 列表;渲染时通过 id 访问 allPanels 中的 meta尺寸队列更新只处理边界与比例不涉及 DOM 实例。
  • 示例字段:id, title, icon, component, initialPosition, tags, flags(如 collapsed, floating)。

更新流程(队列式批处理)

  • 触发条件:当一个面板区发生增删面板、折叠/展开、拖拽分割条、切换 Tab 等事件。
  • 入队:将“变化的面板区”加入其 pendingUpdates 以及受影响链上的目标区(或采用全局 Set 以去重)。
  • 处理:从队列弹出一个区,先计算该区边界与尺寸,再按“受影响列表”逐个更新目标区的子面板尺寸,过程中将新产生的更新继续入队。
  • 终止:队列为空或达到安全迭代上限(防循环保护),保证一次批处理中所有关联区都被稳定更新。

TabGroup 行为约定

  • APIaddTab(panel), closeTab(panelId), activateTab(index)
  • 事件:tabAdded, tabClosed, tabActivated(用于通知面板区更新队列)。
  • 视觉:标签栏 + 内容区,支持拖拽排序、上下文菜单等扩展能力。

目录规划(建议)

  • DockLayoutContainer.vue:顶层容器(挂载五大面板区、调度队列)。
  • Area.vue:单个面板区容器(承载一个或多个子面板区)。
  • TabGroup.vue(或复用现有 components/TabGroup.js):标签页组织与交互。
  • influence.ts:影响关系与队列工具(enqueue/processQueue)。
  • types.ts:类型定义(如上草案)。
  • README.md:本文档。

备注

  • 后续将对接已有的布局协调器(如 LayoutCoordinator)与 storedockPanelStore.js)的尺寸计算接口。
  • 若需要在本目录中实现独立组件,也可提供适配层以与现有容器组件互通。