# Vue页面可视化设计器 - 项目上下文
> **用途**:用于在新环境快速恢复 AI 协作上下文
> **更新时间**:2025-12-22
> **项目路径**:`d:/workspace/fauto-design/draggable-panels`
---
## 📋 项目概述
这是一个基于 **Vue3 + TypeScript + Vite + Element Plus** 的**可视化页面设计器**,通过拖拽操作直接编辑真实的Vue页面文件。
### 核心特性
1. **直接解析Vue文件** - 动态扫描并渲染`src/views`下的页面
2. **拖拽式设计** - 将设计组件拖拽到页面的el-row/el-col上
3. **非侵入式交互** - 通过注入方式绑定事件,不修改页面代码
4. **智能层级选择** - 键盘方向键切换嵌套元素层级
5. **实时视觉反馈** - 拖拽预览 + 拖放区域显示(上/下/左/右)
---
## 🏗️ 项目结构
```
draggable-panels/
├── src/
│ ├── fauto/ # 🔥 设计器核心代码
│ │ ├── Designer.vue # 设计器主入口
│ │ │
│ │ ├── components/ # 基础UI组件
│ │ │ ├── Header.vue # 顶部菜单栏
│ │ │ ├── Footer.vue # 底部状态栏(显示拖拽状态)
│ │ │ ├── MainLayout.vue # 三栏布局容器
│ │ │ ├── Panel.vue # 面板容器
│ │ │ └── Resizer.vue # 面板分隔器
│ │ │
│ │ ├── materials/ # 🎁 物料组件系统
│ │ │ ├── PageManagement/ # 页面管理(树形选择Vue文件)
│ │ │ ├── DesignComponentList/ # 设计组件列表
│ │ │ └── DesignCenter/ # 设计中心(动态渲染页面)
│ │ │ ├── index.vue # 主组件
│ │ │ ├── InteractiveWrapper.vue # 交互包装器(注入事件)
│ │ │ ├── DropZone.vue # 拖放区域指示器
│ │ │ └── DragPreview.vue # 拖拽预览
│ │ │
│ │ ├── designComponents/ # 🎨 设计组件库
│ │ │ ├── TextInput/ # 文本输入框
│ │ │ ├── RadioSelect/ # 单选器
│ │ │ └── GridTable/ # 表格
│ │ │
│ │ ├── plugins/ # 🔌 插件系统(核心功能)
│ │ │ ├── index.ts # 统一导出
│ │ │ ├── interactionStore.ts # 全局交互事件钩子
│ │ │ ├── dragStore.ts # 拖拽状态管理(层级选择)
│ │ │ └── pathUtils.ts # 结构化路径工具
│ │ │
│ │ ├── stores/ # 🗄️ Pinia状态管理
│ │ │ ├── panelStore.ts # 面板布局状态
│ │ │ ├── designStore.ts # 设计组件元数据
│ │ │ └── vueFileStore.ts # Vue文件选择状态
│ │ │
│ │ └── types/ # 📝 类型定义
│ │
│ ├── views/ # 📄 示例页面
│ │ ├── TestPage1.vue # 测试页面1
│ │ ├── TestPage2.vue # 测试页面2
│ │ ├── user/Profile.vue # 用户资料页
│ │ └── dashboard/Overview.vue # 仪表板
│ │
│ ├── router.ts # 路由配置
│ ├── main.ts # 应用入口
│ ├── App.vue # 根组件
│ └── style.css # 全局样式
│
└── vite.config.ts # Vite配置
```
---
## 🔑 核心技术要点
### 1. **Vue页面规范** ⭐
**强制规则**:template的第一层级**有且仅有一个el-row**
**示例**:
```vue
左侧内容
标题
```
**目的**:保证布局可解析性,方便自动生成结构化路径ID
### 2. **结构化路径ID** ⭐
**格式**:`r{n}c{m}r{x}c{y}...`
- `r`: el-row
- `c`: el-col
- 数字:同级索引(从1开始)
**示例**:`r1c2r1c3` 表示:
- 第1个el-row → 第2个el-col → 第1个el-row → 第3个el-col
**实现**:`fauto/plugins/pathUtils.ts`
### 3. **交互事件注入** ⭐
**InteractiveWrapper.vue** 核心流程:
```typescript
// 1. 动态渲染组件
// 2. 挂载后扫描DOM
const injectInteractionEvents = () => {
const rows = containerRef.value.querySelectorAll('.el-row')
const cols = containerRef.value.querySelectorAll('.el-col')
// 3. 为每个元素注入事件
rows.forEach((row) => {
const path = generateElementPath(row) // 生成路径ID
bindElementEvents(row, 'er', path) // 绑定事件
})
}
// 4. 使用MutationObserver监听DOM变化
observer.observe(containerRef.value, { childList: true, subtree: true })
```
### 4. **层级选择机制** ⭐
**核心思想**:当鼠标悬停在嵌套元素上时(如`r1c1r1`),会同时触发`r1c1r1`、`r1c1`、`r1`三个层级。
**解决方案**(`dragStore.ts`):
```typescript
// 1. 收集所有层级节点
const updateHierarchy = (element: HTMLElement) => {
const nodes = []
let current = element
while (current) {
if (current.classList.contains('el-row') || current.classList.contains('el-col')) {
nodes.push({ path, type, element, depth })
}
current = current.parentElement
}
// 按深度排序,最深的在前
nodes.sort((a, b) => b.depth - a.depth)
}
// 2. 键盘切换层级
↑ 键 → selectParentLevel() // 切换到父级
↓ 键 → selectChildLevel() // 切换到子级
Esc → cancelDrag() // 取消拖拽
```
### 5. **拖拽交互优化** ⭐
#### 禁用文本选择
```typescript
// DragPreview.vue
watch(() => dragStore.isDragging, (isDragging) => {
if (isDragging) {
document.body.classList.add('is-dragging')
} else {
document.body.classList.remove('is-dragging')
}
})
```
```css
/* style.css */
body.is-dragging {
user-select: none !important;
cursor: grabbing !important;
}
```
#### 拖拽预览效果
- 跟随鼠标的半透明卡片
- 显示组件图标 + 名称
- Teleport到body避免z-index问题
---
## 🎯 数据流图
```
1. 页面管理
用户点击Vue文件
↓
vueFileStore.selectFile(path)
↓
DesignCenter动态渲染该页面
↓
InteractiveWrapper注入交互事件
2. 拖拽交互
用户拖拽设计组件
↓
dragStore.startDragFromComponentList(id, name)
↓
鼠标移动到页面元素上
↓
dragStore.updateHierarchy(element) // 识别层级
↓
用户按↑↓键切换层级
↓
DropZone显示可放置区域(上/下/左/右)
↓
用户点击区域确认
↓
dragStore.confirmDrop()
↓
Footer显示拖放记录:TextInput → r1c1 左侧
```
---
## 🛠️ 快速开始
### 访问设计器
```
http://localhost:5173/draggable
```
### 使用流程
1. 点击左侧"页面管理"物料
2. 在树形列表中选择一个Vue页面
3. 页面在"设计中心"中渲染
4. 从"设计组件列表"拖拽组件
5. 移动到页面的el-row或el-col上
6. 使用↑↓键切换层级
7. 点击放置方向(上/下/左/右)
8. 查看Footer中的拖放记录
---
## 📝 开发规范
### 创建符合规范的Vue页面
```vue
```
### 添加设计组件
1. 在`src/fauto/designComponents/`下创建目录
2. 添加`index.vue`和`index.json`
3. 自动在列表中显示
### 插件开发
所有与页面解析、交互相关的代码放在`src/fauto/plugins/`
---
## 🚀 下一步计划
1. **拖放后修改源文件** - 通过API将操作写入.vue文件
2. **属性编辑器** - 展示和编辑组件属性
3. **热更新同步** - 修改后自动刷新页面
4. **撤销/重做** - 操作历史记录
---
## 📚 相关文档
- **详细设计文档**:`项目设计文档.md`
- **技术选型**:Vue3 + TypeScript + Element Plus + Pinia
- **构建工具**:Vite 7.3.0
---
## 💡 核心创新点
1. **非侵入式设计** - 无需修改Vue页面代码即可实现拖拽设计
2. **智能层级选择** - 自动识别嵌套结构,精准定位目标位置
3. **实时视觉反馈** - 完善的拖拽交互体验
4. **结构化路径** - 人类可读的元素定位方式
---
**最后更新**:2025-12-22
**AI协作建议**:优先阅读本文档的"核心技术要点"部分,理解项目的设计理念和实现方式