# 可拖拽子窗口项目设计文档 ## 项目概述 本项目是一个基于 Vite + Vue3 + TypeScript 的可拖拽子窗口系统,模仿 IDE(如 IntelliJ IDEA、Visual Studio)的界面设计,提供多区域可拖拽的窗口管理功能。 ## 技术架构 ### 核心技术栈 - **构建工具**: Vite 7.3.0 - **前端框架**: Vue 3.5.24 (Composition API) - **状态管理**: Pinia 3.0.4 - **类型系统**: TypeScript - **拖拽库**: vuedraggable 4.1.0 - **样式**: CSS Modules + Scoped Styles ### 项目结构 ``` src/ ├── assets/ # 静态资源 ├── components/ # 核心UI组件 │ ├── Header.vue # 顶部菜单栏 │ ├── Footer.vue # 底部状态栏 │ ├── MainLayout.vue # 主布局容器 │ ├── Panel.vue # 面板容器 │ └── Resizer.vue # 面板分隔器 ├── materials/ # 物料组件系统 │ ├── index.ts # 物料组件注册中心 │ ├── TextEditor/ # 文本编辑器 │ ├── TreeViewer/ # 树形展示器 │ ├── DataTable/ # 数据表格 │ ├── TestWidget*/ # 测试组件 │ ├── DesignComponentList/ # 设计组件列表 │ └── DesignCenter/ # 设计中心 ├── designComponents/ # 设计组件库 │ ├── TextInput/ # 文本输入框 │ ├── RadioSelect/ # 单选器 │ └── GridTable/ # 表格组件 ├── stores/ # 状态管理 │ ├── panelStore.ts # 面板布局状态 │ └── designStore.ts # 设计中心状态 ├── types/ # TypeScript 类型定义 └── App.vue # 应用入口 ``` ## 核心功能模块 ### 1. 面板系统 (Panel System) #### 布局结构 - **Header**: 固定顶部,包含菜单和新增窗口按钮 - **MainLayout**: 三区域布局(左/中/右) - **Panel**: 可拖拽的面板容器 - **Footer**: 固定底部,显示时间和状态信息 #### 拖拽实现 使用 `vuedraggable` 库实现跨面板的 Tab 拖拽: ```vue ``` ### 2. 物料组件系统 (Material System) #### 规范标准 遵循统一的物料组件规范: 1. 每个组件独立文件夹 2. 包含 `index.vue`(组件实现)和 `index.json`(元数据) 3. `index.json` 定义:名称、描述、属性及默认值 #### 组件状态管理 - 使用 `materialState` 属性传递组件状态 - 通过 `update:state` 事件实现状态更新 - 物料组件状态独立存储,组件关闭后状态仍保留 #### 状态持久化 通过自定义 Vite 插件实现 API 中间件: - `/api/config`: 布局配置读写 - `/api/material-states`: 物料组件状态读写 - `/api/design-components`: 设计组件元数据读取 - `/api/design-state`: 设计中心状态读写 ### 3. 设计组件系统 (Design System) #### 组件构成 1. **设计组件库** (`designComponents/`) - TextInput: 文本输入框(属性:label, width, maxLength) - RadioSelect: 单选器(属性:options) - GridTable: 表格(属性:rows, columns, headers) 2. **物料组件** - DesignComponentList: 展示可用设计组件 - DesignCenter: 展示已添加的设计组件实例 - TreeViewer: 展示设计中心组件列表(支持拖拽排序) - DataTable: 展示选中组件的属性(支持编辑) #### 跨组件联动机制 1. 点击 DesignComponentList 中的组件添加到 DesignCenter 2. 点击 DesignCenter 中的组件,在 DataTable 中展示其属性 3. 在 TreeViewer 中拖拽组件调整 DesignCenter 的顺序 4. 在 DataTable 中双击属性值进行编辑 ## 状态管理设计 ### PanelStore (面板状态) 管理整个应用的布局和物料组件状态: - `layout`: 三区域面板配置 - `materialStates`: 物料组件状态独立存储 - 提供 Tab 操作 API(添加、关闭、移动、激活) ### DesignStore (设计中心状态) 管理设计组件系统的状态: - `components`: 已添加的设计组件实例列表 - `selectedId`: 当前选中的组件实例ID - `componentMetas`: 设计组件元数据缓存 ## 实现细节 ### 1. 拖拽功能优化 - 使用 `:list` 属性而非 `v-model` 解决拖拽位置问题 - 实现跨面板 Tab 拖拽 - 面板宽度可调整(通过 Resizer 组件) ### 2. 状态持久化策略 - 布局配置和物料状态分别存储 - 使用防抖机制避免频繁保存(TextEditor 500ms) - 组件移除后状态仍保留 ### 3. 组件通信机制 - 父子组件:Props / Events - 兄弟组件:通过 Pinia Store - 物料组件:`materialState` / `update:state` ### 4. 性能优化 - 使用 `defineAsyncComponent` 异步加载物料组件 - 使用 `markRaw` 避免不必要的响应式转换 - 使用 `computed` 缓存派生数据 ## API 设计 ### 配置管理 API ``` GET /api/config # 获取布局配置 POST /api/config # 保存布局配置 GET /api/material-states # 获取物料组件状态 POST /api/material-states # 保存物料组件状态 ``` ### 设计系统 API ``` GET /api/design-components # 获取设计组件元数据 GET /api/design-state # 获取设计中心状态 POST /api/design-state # 保存设计中心状态 ``` ## 开发规范 ### 代码规范 1. 使用 TypeScript 严格模式 2. 组件 Props 必须明确定义类型 3. 使用 Composition API 组织代码逻辑 4. 样式使用 scoped 避免全局污染 ### 组件开发规范 1. 遵循物料组件标准化规范 2. 状态通过 `materialState` 接收,通过 `update:state` 更新 3. 实现防抖保存机制避免频繁 IO 4. 提供清晰的组件文档(index.json) ### 状态管理规范 1. 使用 Pinia 进行全局状态管理 2. 状态变更必须通过 Store 的方法 3. 复杂状态逻辑封装在 Store 内部 4. 状态持久化与 UI 逻辑分离 ## 扩展性设计 ### 新增物料组件 1. 在 `materials/` 目录下创建组件文件夹 2. 实现 `index.vue` 和 `index.json` 3. 在 `materials/index.ts` 中注册组件 ### 新增设计组件 1. 在 `designComponents/` 目录下创建组件文件夹 2. 实现 `index.vue` 和 `index.json` 3. 在 DesignComponentList 中会自动显示 ### 功能扩展 1. 面板系统支持更多布局模式 2. 物料组件支持更多交互类型 3. 设计系统支持更复杂的属性编辑器 ## 总结 本项目实现了完整的可拖拽子窗口系统,具备良好的架构设计和扩展性。通过物料组件系统和设计组件系统的分离,既满足了基础的窗口管理需求,又提供了高级的设计能力。状态持久化机制确保了用户体验的连续性,而规范化的开发流程保证了项目的可维护性。