23
This commit is contained in:
199
draggable-panels/项目设计文档.md
Normal file
199
draggable-panels/项目设计文档.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# 可拖拽子窗口项目设计文档
|
||||
|
||||
## 项目概述
|
||||
|
||||
本项目是一个基于 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
|
||||
<draggable
|
||||
:list="panel.tabs"
|
||||
group="tabs"
|
||||
item-key="id"
|
||||
:animation="150"
|
||||
>
|
||||
```
|
||||
|
||||
### 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. 设计系统支持更复杂的属性编辑器
|
||||
|
||||
## 总结
|
||||
|
||||
本项目实现了完整的可拖拽子窗口系统,具备良好的架构设计和扩展性。通过物料组件系统和设计组件系统的分离,既满足了基础的窗口管理需求,又提供了高级的设计能力。状态持久化机制确保了用户体验的连续性,而规范化的开发流程保证了项目的可维护性。
|
||||
Reference in New Issue
Block a user