177 lines
4.9 KiB
Markdown
177 lines
4.9 KiB
Markdown
# Vue页面可视化设计器 - 项目上下文
|
||
|
||
> **用途**:AI 协作快速恢复上下文
|
||
> **更新时间**:2026-01-20
|
||
> **项目路径**:`d:/workspace/fauto-design`
|
||
|
||
---
|
||
|
||
## 📋 项目概述
|
||
|
||
基于 **Vue3 + TypeScript + Vite + Element Plus** 的**可视化页面设计器**,通过拖拽操作直接编辑真实的Vue源文件。
|
||
|
||
### 核心特性
|
||
|
||
1. **直接解析Vue文件** - 动态扫描并渲染 `src/views` 下的页面
|
||
2. **拖拽式设计** - 将组件拖拽到页面的 el-row/el-col 上
|
||
3. **两阶段拖拽** - 源选择阶段 → 目标选择阶段
|
||
4. **智能层级选择** - 键盘 ↑↓ 切换嵌套元素层级
|
||
5. **源码实时修改** - 后端服务解析AST并修改Vue文件
|
||
|
||
---
|
||
|
||
## 🏗️ 项目结构
|
||
|
||
```
|
||
fauto-design/
|
||
├── draggable-panels/ # 前端项目
|
||
│ └── src/
|
||
│ ├── fauto/ # 🔥 设计器核心
|
||
│ │ ├── Designer.vue # 设计器主入口
|
||
│ │ ├── components/ # 基础UI组件
|
||
│ │ ├── materials/ # 物料组件系统
|
||
│ │ │ ├── DesignCenter/ # 设计中心
|
||
│ │ │ │ ├── InteractiveWrapper.vue # 交互注入器
|
||
│ │ │ │ └── DropZone.vue # 拖放指示器
|
||
│ │ │ ├── DesignComponentList/ # 设计组件列表
|
||
│ │ │ └── PageManager/ # 页面管理
|
||
│ │ ├── designComponents/ # 设计组件库
|
||
│ │ ├── plugins/ # 🔌 核心插件
|
||
│ │ │ ├── dragStore.ts # 拖拽状态管理
|
||
│ │ │ ├── interactionStore.ts
|
||
│ │ │ └── pathUtils.ts # 路径工具
|
||
│ │ └── stores/ # Pinia状态
|
||
│ └── views/ # 示例页面
|
||
│
|
||
└── vue-template-service/ # 后端服务(Node.js)
|
||
└── src/
|
||
├── index.js # Express API
|
||
└── services/
|
||
└── templateService.js # Vue模板解析修改
|
||
```
|
||
|
||
---
|
||
|
||
## 🔑 核心技术要点
|
||
|
||
### 1. Vue页面规范 ⭐
|
||
|
||
**强制规则**:template 第一层级**有且仅有一个 el-row**
|
||
|
||
```vue
|
||
<template>
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">内容</el-col>
|
||
<el-col :span="12">
|
||
<el-row> <!-- 支持嵌套 -->
|
||
<el-col :span="24">嵌套内容</el-col>
|
||
</el-row>
|
||
</el-col>
|
||
</el-row>
|
||
</template>
|
||
```
|
||
|
||
### 2. 结构化路径ID ⭐
|
||
|
||
**格式**:`r{n}c{m}...`(r=row, c=col, 数字=索引从1开始)
|
||
|
||
**示例**:`r1c2r1c3` = 第1个row → 第2个col → 第1个row → 第3个col
|
||
|
||
### 3. 两阶段拖拽 ⭐⭐
|
||
|
||
| 阶段 | 触发 | ↑↓键功能 | 拖放方向 |
|
||
|------|------|----------|---------|
|
||
| **源选择** | 点击元素 | 切换源层级 | 不显示 |
|
||
| **目标选择** | 移到其他元素 | 切换目标层级 | 显示 |
|
||
|
||
```typescript
|
||
// dragStore.ts 核心状态
|
||
dragPhase: 'source' | 'target'
|
||
confirmedSource: { path, type, element }
|
||
```
|
||
|
||
### 4. 跨类型拖放 ⭐
|
||
|
||
- **同类型**:el-row→el-row 显示上/下,el-col→el-col 显示左/右
|
||
- **跨类型**:el-row→el-col 或 el-col→el-row 显示"放入内部"(inside)
|
||
|
||
### 5. 后端模板服务 ⭐⭐
|
||
|
||
**API**:`POST http://localhost:3001/api/move-element`
|
||
|
||
```json
|
||
{
|
||
"pagePath": "views/TestPage1.vue",
|
||
"source": "r1c1",
|
||
"target": "r1c2",
|
||
"direction": "right" // top|bottom|left|right|inside
|
||
}
|
||
```
|
||
|
||
**技术栈**:
|
||
- `@vue/compiler-sfc` - 解析Vue SFC
|
||
- `@vue/compiler-dom` - 解析template AST
|
||
- 字符串操作移动元素(保持原始格式)
|
||
|
||
---
|
||
|
||
## 🎯 数据流
|
||
|
||
```
|
||
用户点击元素开始拖拽
|
||
↓
|
||
dragStore.startDragFromCanvas() → 源选择阶段
|
||
↓
|
||
按↑↓键切换源层级
|
||
↓
|
||
移动到其他元素 → dragStore.enterTargetPhase() → 目标选择阶段
|
||
↓
|
||
按↑↓键切换目标层级,显示DropZone
|
||
↓
|
||
松开鼠标 → dragStore.confirmDrop()
|
||
↓
|
||
调用后端API → templateService.moveElement()
|
||
↓
|
||
修改Vue源文件 → 页面热更新
|
||
```
|
||
|
||
---
|
||
|
||
## 🛠️ 快速开始
|
||
|
||
```bash
|
||
# 启动前端(端口5173)
|
||
cd draggable-panels
|
||
npm run dev
|
||
|
||
# 启动后端(端口3001)
|
||
cd vue-template-service
|
||
node src/index.js
|
||
```
|
||
|
||
**访问**:http://localhost:5173/draggable
|
||
|
||
---
|
||
|
||
## 📝 关键文件
|
||
|
||
| 文件 | 用途 |
|
||
|------|------|
|
||
| `plugins/dragStore.ts` | 拖拽状态、两阶段逻辑、层级选择 |
|
||
| `materials/DesignCenter/InteractiveWrapper.vue` | 交互注入、键盘监听、拖放确认 |
|
||
| `materials/DesignCenter/DropZone.vue` | 拖放方向指示器 |
|
||
| `vue-template-service/src/services/templateService.js` | AST解析、元素移动 |
|
||
|
||
---
|
||
|
||
## 💡 注意事项
|
||
|
||
1. 拖拽时会禁用文本选择(`user-select: none`)
|
||
2. 使用全局鼠标事件获取悬停位置(避免 pointer-events 问题)
|
||
3. 移动元素时保持相对缩进关系
|
||
4. 前后端都需要运行才能完成拖放后的源码修改
|
||
|
||
---
|
||
|
||
**最后更新**:2026-01-20
|