Compare commits
2 Commits
f858f69daa
...
83bafa4e1e
| Author | SHA1 | Date | |
|---|---|---|---|
| 83bafa4e1e | |||
| 7d2ce711dd |
326
draggable-panels/PROJECT_CONTEXT.md
Normal file
326
draggable-panels/PROJECT_CONTEXT.md
Normal file
@@ -0,0 +1,326 @@
|
|||||||
|
# 拖拽面板设计器 - 项目上下文总结
|
||||||
|
|
||||||
|
> **用途**:用于在新电脑快速恢复 AI 协作上下文
|
||||||
|
> **生成时间**:2025-12-20
|
||||||
|
> **项目路径**:`/Volumes/mypan/ui/draggable-panels`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 项目概述
|
||||||
|
|
||||||
|
这是一个基于 **Vue3 + TypeScript + Vite** 的**可拖拽面板设计器**项目,类似 IDE 界面(IDEA/VS Code)的多面板布局,支持:
|
||||||
|
|
||||||
|
- 🎯 三栏面板布局(左/中/右可调整宽度)
|
||||||
|
- 🎨 Tab 可拖拽、跨面板移动
|
||||||
|
- 🧩 物料组件系统(自动扫描注册)
|
||||||
|
- 🎭 设计组件系统(可视化编辑、属性绑定)
|
||||||
|
- 💾 状态持久化(通过模拟 API)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
draggable-panels/
|
||||||
|
├── src/
|
||||||
|
│ ├── fauto/ # 🔥 设计器核心代码(所有功能都在这里)
|
||||||
|
│ │ ├── Designer.vue # 设计器主入口页面
|
||||||
|
│ │ ├── components/ # 设计器基础组件
|
||||||
|
│ │ │ ├── Header.vue # 顶部菜单栏(打开项目/窗口菜单)
|
||||||
|
│ │ │ ├── Footer.vue # 底部状态栏
|
||||||
|
│ │ │ ├── MainLayout.vue # 三栏布局容器
|
||||||
|
│ │ │ ├── Panel.vue # 单个面板(含 Tab 列表 + 内容区)
|
||||||
|
│ │ │ └── Resizer.vue # 面板间拖拽分割线
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── materials/ # 🎁 物料组件(8个)
|
||||||
|
│ │ │ ├── index.ts # ✅ 自动扫描所有 */index.vue 和 */index.json
|
||||||
|
│ │ │ ├── DesignComponentList/ # 可选设计组件列表
|
||||||
|
│ │ │ ├── TreeViewer/ # 树形结构查看器(已添加实例列表)
|
||||||
|
│ │ │ ├── DesignCenter/ # 设计中心(组件预览面板)
|
||||||
|
│ │ │ ├── DataTable/ # 属性表格编辑器
|
||||||
|
│ │ │ ├── TextEditor/ # 文本编辑器(支持状态持久化)
|
||||||
|
│ │ │ ├── TestWidget1/2/3/ # 测试组件
|
||||||
|
│ │ │ └── [每个物料包含]
|
||||||
|
│ │ │ ├── index.vue # 组件实现
|
||||||
|
│ │ │ └── index.json # 组件元数据(name/description)
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── designComponents/ # 🎨 设计组件(3个)
|
||||||
|
│ │ │ ├── TextInput/ # 文本输入框
|
||||||
|
│ │ │ ├── RadioSelect/ # 单选器
|
||||||
|
│ │ │ ├── GridTable/ # 表格
|
||||||
|
│ │ │ └── [每个设计组件包含]
|
||||||
|
│ │ │ ├── index.vue # Vue 组件定义
|
||||||
|
│ │ │ └── index.json # 元数据(name/description/props)
|
||||||
|
│ │ │
|
||||||
|
│ │ ├── stores/ # 🗄️ Pinia 状态管理
|
||||||
|
│ │ │ ├── panelStore.ts # 面板布局 + 物料状态管理
|
||||||
|
│ │ │ └── designStore.ts # 设计组件实例管理(✅ 本地自动扫描)
|
||||||
|
│ │ │
|
||||||
|
│ │ └── types/ # 📝 TypeScript 类型定义
|
||||||
|
│ │ └── index.ts # Panel/TabItem/MaterialInfo 等
|
||||||
|
│ │
|
||||||
|
│ ├── views/ # 普通视图
|
||||||
|
│ │ └── HelloWorld.vue # 首页欢迎页
|
||||||
|
│ │
|
||||||
|
│ ├── router.ts # 🛤️ 路由配置(/ 和 /draggable)
|
||||||
|
│ ├── main.ts # 应用入口
|
||||||
|
│ ├── App.vue # 根组件(仅路由容器)
|
||||||
|
│ └── style.css # 全局样式
|
||||||
|
│
|
||||||
|
├── package.json # 依赖配置
|
||||||
|
└── vite.config.ts # Vite 配置
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔑 核心技术要点
|
||||||
|
|
||||||
|
### 1. **路由设计**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// src/router.ts
|
||||||
|
'/' → HelloWorld 欢迎页
|
||||||
|
'/draggable' → Designer 设计器主页面(fauto/Designer.vue)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **物料组件自动注册** ⭐
|
||||||
|
|
||||||
|
**文件**:`src/fauto/materials/index.ts`
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ✅ 使用 import.meta.glob 自动扫描
|
||||||
|
const vueModules = import.meta.glob('./*/index.vue')
|
||||||
|
const jsonModules = import.meta.glob('./*/index.json', { eager: true })
|
||||||
|
|
||||||
|
// 自动构建组件映射表和信息列表
|
||||||
|
export const materialComponents: Record<string, Component> = {}
|
||||||
|
export const materialList: MaterialInfo[] = []
|
||||||
|
```
|
||||||
|
|
||||||
|
**新增物料步骤**:
|
||||||
|
1. 在 `materials/` 下创建新目录(如 `MyWidget/`)
|
||||||
|
2. 添加 `index.vue`(组件实现)
|
||||||
|
3. 添加 `index.json`(元数据)
|
||||||
|
4. **无需修改任何注册代码**,自动生效!
|
||||||
|
|
||||||
|
### 3. **设计组件自动加载** ⭐
|
||||||
|
|
||||||
|
**最近修复**(2025-12-20):
|
||||||
|
|
||||||
|
**designStore.ts** - 从远程 API 改为本地扫描:
|
||||||
|
```typescript
|
||||||
|
// ✅ 使用 eager: true 同步加载
|
||||||
|
const designComponentMetaModules = import.meta.glob('../designComponents/*/index.json', { eager: true })
|
||||||
|
|
||||||
|
// 自动构建元数据列表
|
||||||
|
const loadComponentMetas = async () => {
|
||||||
|
const metas: DesignComponentMeta[] = []
|
||||||
|
for (const path in designComponentMetaModules) {
|
||||||
|
const id = match[1] // 如 'TextInput'
|
||||||
|
metas.push({ id, name, description, props })
|
||||||
|
}
|
||||||
|
componentMetas.value = metas
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**DesignCenter.vue** - 组件预览渲染:
|
||||||
|
```typescript
|
||||||
|
// ✅ 使用 eager: true 确保同步加载
|
||||||
|
const designComponentModules = import.meta.glob('../../designComponents/*/index.vue', { eager: true })
|
||||||
|
|
||||||
|
// 构建组件映射(用于 <component :is="...">)
|
||||||
|
const designComponentMap: Record<string, any> = {}
|
||||||
|
for (const path in designComponentModules) {
|
||||||
|
const mod = designComponentModules[path] as any
|
||||||
|
designComponentMap[id] = markRaw(mod.default || mod)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. **状态同步机制** ⭐
|
||||||
|
|
||||||
|
**TreeViewer.vue** - 实例列表实时同步(最近修复):
|
||||||
|
```typescript
|
||||||
|
// ✅ 改用 watch 替代 $subscribe(更稳定)
|
||||||
|
watch(
|
||||||
|
() => designStore.components,
|
||||||
|
(newVal) => {
|
||||||
|
localComponents.value = [...newVal]
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true }
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. **状态持久化**
|
||||||
|
|
||||||
|
- **panelStore**:管理面板布局 + 物料组件状态
|
||||||
|
- `loadConfig()` / `saveConfig()` → `/api/config`
|
||||||
|
- `getMaterialState()` / `updateMaterialState()` → `/api/material-states`
|
||||||
|
|
||||||
|
- **designStore**:管理设计组件实例
|
||||||
|
- `loadState()` / `saveState()` → `/api/design-state`
|
||||||
|
|
||||||
|
**注意**:目前使用 `fetch('/api/...')` 模拟持久化,实际会失败但不影响运行。如需真实持久化,可改用 localStorage 或搭建后端。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 数据流图
|
||||||
|
|
||||||
|
```
|
||||||
|
用户操作
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ Header.vue - 点击"窗口"菜单 │
|
||||||
|
│ → panelStore.openMaterial('TreeViewer') │
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ Panel.vue - 渲染 Tab + 加载物料组件 │
|
||||||
|
│ → <component :is="getMaterialComponent(id)"> │
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ DesignComponentList - 点击"文本输入框" │
|
||||||
|
│ → designStore.addComponent('TextInput') │
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ TreeViewer - watch 监听 components 变化 │
|
||||||
|
│ → 自动刷新实例列表 │
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ DesignCenter - 渲染组件预览 │
|
||||||
|
│ → <component :is="getComponent(componentId)"> │
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
↓
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ DataTable - 编辑属性 │
|
||||||
|
│ → designStore.updateComponentProps(id, key, val)│
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 已解决的关键问题
|
||||||
|
|
||||||
|
### 问题 1:设计组件列表不显示
|
||||||
|
**时间**:2025-12-20
|
||||||
|
**原因**:`designStore.loadComponentMetas()` 使用 `fetch('/api/design-components')`,无后端导致 `componentMetas` 为空
|
||||||
|
**解决**:改用 `import.meta.glob` 自动扫描本地 `designComponents/*/index.json`
|
||||||
|
|
||||||
|
### 问题 2:TreeViewer 列表不更新
|
||||||
|
**原因**:使用 Pinia 的 `$subscribe` 监听 mutation,逻辑复杂且不稳定
|
||||||
|
**解决**:改用 Vue 的 `watch(() => designStore.components)` 直接监听
|
||||||
|
|
||||||
|
### 问题 3:DesignCenter 组件不渲染
|
||||||
|
**原因**:`import.meta.glob` 未设置 `eager: true`,导致组件映射表构建失败
|
||||||
|
**解决**:添加 `{ eager: true }` 并使用 `mod.default || mod` 获取组件定义
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 依赖清单
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"vue": "^3.5.24", // Vue 3 框架
|
||||||
|
"vue-router": "^4.6.4", // 路由管理
|
||||||
|
"pinia": "^3.0.4", // 状态管理
|
||||||
|
"vuedraggable": "^4.1.0" // 拖拽功能
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"vite": "^7.2.4", // 构建工具
|
||||||
|
"typescript": "~5.9.3", // TypeScript
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 启动命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 安装依赖
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# 2. 启动开发服务器
|
||||||
|
npm run dev
|
||||||
|
# 访问 http://localhost:5173/draggable
|
||||||
|
|
||||||
|
# 3. 构建生产版本
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 后续可优化方向
|
||||||
|
|
||||||
|
### 🔧 功能增强
|
||||||
|
1. **真实持久化**
|
||||||
|
- 选项 A:改用 `localStorage` 替代模拟 API
|
||||||
|
- 选项 B:搭建 Node.js 后端(Express + fs.writeFile)
|
||||||
|
|
||||||
|
2. **拖拽增强**
|
||||||
|
- 支持面板间 Tab 跨级拖动
|
||||||
|
- 树形组件支持父子节点拖拽
|
||||||
|
|
||||||
|
3. **设计器功能**
|
||||||
|
- 实现拖拽生成 Vue 文件(模板引擎)
|
||||||
|
- 接入 Element Plus 组件库作为设计组件源
|
||||||
|
|
||||||
|
4. **开发体验**
|
||||||
|
- 添加 ESLint + Prettier 代码规范
|
||||||
|
- 添加单元测试(Vitest)
|
||||||
|
|
||||||
|
### 🎨 界面优化
|
||||||
|
- 添加主题切换(暗色/亮色)
|
||||||
|
- 面板大小记忆功能
|
||||||
|
- 快捷键支持(Ctrl+S 保存等)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 给 AI 的关键提示
|
||||||
|
|
||||||
|
### 如果遇到"自动扫描不生效"
|
||||||
|
1. 检查是否添加了 `{ eager: true }` 选项
|
||||||
|
2. 确认路径匹配正则是否正确(`/designComponents\/(.+)\/index\.vue$/`)
|
||||||
|
3. 验证文件夹下是否有 `index.vue` 和 `index.json`
|
||||||
|
|
||||||
|
### 如果组件不渲染
|
||||||
|
1. 检查 `import.meta.glob` 是否使用 `eager: true`
|
||||||
|
2. 确认使用 `mod.default || mod` 获取组件
|
||||||
|
3. 对于动态组件,确保使用 `markRaw()` 包装
|
||||||
|
|
||||||
|
### 如果状态不同步
|
||||||
|
1. 优先使用 Vue 的 `watch` 而非 Pinia 的 `$subscribe`
|
||||||
|
2. 设置 `{ deep: true, immediate: true }` 确保深度监听
|
||||||
|
3. 使用 `[...array]` 创建新数组触发响应式更新
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📞 联系方式
|
||||||
|
|
||||||
|
**项目负责人**:[你的信息]
|
||||||
|
**Git 仓库**:[如果有的话]
|
||||||
|
**文档更新**:2025-12-20
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ 快速检查清单(给新 AI)
|
||||||
|
|
||||||
|
当你接手这个项目时,请确认以下内容:
|
||||||
|
|
||||||
|
- [ ] 项目已正常启动(`npm run dev`)
|
||||||
|
- [ ] 访问 `/draggable` 能看到设计器界面
|
||||||
|
- [ ] 点击"窗口"菜单能打开物料组件
|
||||||
|
- [ ] "设计组件列表"显示 3 个组件(TextInput/RadioSelect/GridTable)
|
||||||
|
- [ ] 点击设计组件后,TreeViewer 能显示新实例
|
||||||
|
- [ ] DesignCenter 能正确渲染组件预览
|
||||||
|
- [ ] DataTable 能编辑组件属性
|
||||||
|
|
||||||
|
如果以上任一项失败,请参考"已解决的关键问题"章节。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**🎉 恭喜!你已经完全掌握了这个项目的上下文,可以继续开发了!**
|
||||||
@@ -55,5 +55,5 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"selectedId": "xazr6j9",
|
"selectedId": "xazr6j9",
|
||||||
"lastUpdated": "2025-12-20T14:50:43.062Z"
|
"lastUpdated": "2025-12-20T15:21:31.411Z"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user