Files
fauto-design/draggable-panels/项目设计文档.md
2025-12-22 23:20:40 +08:00

280 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Vue页面可视化设计器项目文档
## 项目概述
本项目是一个基于 Vite + Vue3 + TypeScript 的**可视化页面设计器**通过拖拽操作直接编辑真实的Vue页面文件实现低代码页面快速构建。
## 核心特性
1. **直接解析Vue文件** - 动态渲染真实的.vue页面
2. **拖拽式设计** - 将设计组件拖拽到页面的el-row/el-col上
3. **层级选择** - 通过键盘方向键切换嵌套元素的选中层级
4. **实时预览** - 拖拽时显示放置方向(上/下/左/右)
5. **结构化ID** - 自动生成路径ID如r1c2r1c1
## 技术架构
### 核心技术栈
- **构建工具**: Vite 7.3.0
- **前端框架**: Vue 3.5.24 (Composition API)
- **状态管理**: Pinia 3.0.4
- **类型系统**: TypeScript
- **拖拽库**: vuedraggable 4.1.0
- **样式**: CSS Modules + Scoped Styles
### 项目结构
```
src/
├── fauto/ # 核心功能模块
│ ├── components/ # UI组件
│ │ ├── Header.vue # 顶部菜单栏
│ │ ├── Footer.vue # 底部状态栏(显示拖拽状态)
│ │ ├── MainLayout.vue # 主布局容器
│ │ ├── Panel.vue # 面板容器
│ │ └── Resizer.vue # 面板分隔器
│ ├── materials/ # 物料组件系统
│ │ ├── PageManagement/ # 页面管理树形选择Vue文件
│ │ ├── DesignComponentList/ # 设计组件列表
│ │ └── DesignCenter/ # 设计中心(动态渲染页面)
│ ├── designComponents/ # 设计组件库
│ │ ├── TextInput/ # 文本输入框
│ │ ├── RadioSelect/ # 单选器
│ │ └── GridTable/ # 表格组件
│ ├── plugins/ # 插件系统(交互事件、拖拽管理)
│ │ ├── interactionStore.ts # 全局交互钩子
│ │ ├── dragStore.ts # 拖拽状态管理
│ │ └── pathUtils.ts # 结构化路径工具
│ ├── stores/ # 状态管理
│ │ ├── panelStore.ts # 面板布局状态
│ │ ├── designStore.ts # 设计组件元数据
│ │ └── vueFileStore.ts # Vue文件选择状态
│ └── Designer.vue # 设计器主入口
├── views/ # 示例页面(测试用)
└── App.vue # 应用入口
```
## 核心功能模块
### 1. 页面管理系统
#### 功能说明
- 动态扫描`src/views`目录下的所有Vue文件
- 以树形结构展示文件夹和页面
- 点击选中后在设计中心动态渲染
#### 技术实现
```typescript
// 使用import.meta.glob动态扫描
const viewModules = import.meta.glob('../../../views/**/*.vue')
// 异步加载选中的组件
const loader = viewModules[selectedFilePath]
const component = defineAsyncComponent(loader)
```
### 2. 设计中心系统
#### InteractiveWrapper交互包装器
**作用**为动态渲染的Vue页面注入交互事件
**核心功能**
1. 自动扫描页面中的el-row和el-col
2. 为每个元素注入结构化路径ID`r1c2`
3. 绑定交互事件(悬停、点击、拖拽)
4. 使用MutationObserver监听DOM变化
#### DropZone拖放区域指示器
**作用**:拖拽时显示可放置区域
**显示规则**
- el-row显示 **上方****下方** 两个区域
- el-col显示 **左侧****右侧** 两个区域
#### DragPreview拖拽预览
跟随鼠标显示正在拖拽的内容,提供视觉反馈。
### 3. 插件系统 (fauto/plugins)
#### interactionStore交互状态管理
管理所有交互事件的全局状态:
- `hoverTarget`: 当前悬停的元素
- `selectedTarget`: 当前选中的元素
- 提供全局事件钩子hover, click, longpress, drag, release
#### dragStore拖拽状态管理
管理拖拽操作的复杂状态:
**核心状态**
- `dragSource`: 拖拽源(设计组件/画布元素)
- `hierarchyNodes`: 当前悬停位置的所有层级节点
- `selectedHierarchyIndex`: 当前选中的层级索引
- `hoverDirection`: 当前悬停的拖放方向
- `lastDropRecord`: 最后一次拖放记录
**层级选择机制**
- 鼠标悬停在嵌套元素上时,自动识别所有父级节点
- 默认选中最深层级
- **↑键**:切换到父级
- **↓键**:切换到子级
- **Esc键**:取消拖拽
#### pathUtils路径工具
生成和解析结构化路径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
## 状态管理设计
### PanelStore面板状态
管理整个应用的布局和物料组件状态:
- `layout`: 三区域面板配置
- `materialStates`: 物料组件状态独立存储
- 提供 Tab 操作 API添加、关闭、移动、激活
### DesignStore设计组件元数据
管理设计组件的元数据:
- `componentMetas`: 设计组件元数据列表
- `loadComponentMetas()`: 动态扫描设计组件目录
- `getComponentMeta()`: 获取指定组件的元数据
### VueFileStoreVue文件状态
管理页面管理的选中状态:
- `selectedFilePath`: 当前选中的文件路径
- `selectedFileName`: 当前选中的文件名
- `selectFile()`: 选中指定文件
### InteractionStore / DragStore
见**插件系统**部分
## 实现细节
### 1. Vue页面规范
**强制规则**template的第一层级**有且仅有一个el-row**
**目的**:保证布局可解析性,方便自动生成结构化路径
示例:
```vue
<template>
<el-row :gutter="20">
<el-col :span="12">
<div class="design-component">左侧内容</div>
</el-col>
<el-col :span="12">
<el-row :gutter="10">
<el-col :span="24">
<div class="design-component">标题</div>
</el-col>
</el-row>
</el-col>
</el-row>
</template>
```
### 2. 拖拽交互优化
#### 禁用文本选择
拖拽时给body添加`is-dragging`类,设置`user-select: none`
#### 拖拽预览效果
DragPreview组件跟随鼠标显示
- 组件图标 + 名称
- 动画效果(缩放 + 淡入)
- Teleport到body避免z-index问题
### 3. 层级选择实现
```typescript
// 递归遍历DOM生成层级节点
const updateHierarchy = (element: HTMLElement) => {
const nodes: HierarchyNode[] = []
let current: HTMLElement | null = 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)
}
```
### 4. 性能优化
- 使用 `defineAsyncComponent` 异步加载页面
- 使用 `MutationObserver` 监听DOM变化
- 防止重复绑定(`data-fauto-bindend`属性)
- 使用 `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 # 保存设计中心状态
```
## 开发规范
### Vue页面结构规范
1. template第一层级有且仅有一个el-row
2. el-row内只能包含el-col或div设计组件
3. div使用class="design-component"标识
### 代码规范
1. 使用 TypeScript 严格模式
2. 组件 Props 必须明确定义类型
3. 使用 Composition API 组织代码逻辑
4. 样式使用 scoped 避免全局污染
### 组件开发规范
1. 遵循物料组件标准化规范
2. 每个组件包含`index.vue``index.json`
3. 插件相关代码放在`fauto/plugins`目录
### 状态管理规范
1. 使用 Pinia 进行全局状态管理
2. 状态变更必须通过 Store 的方法
3. 复杂状态逻辑封装在 Store 内部
## 扩展性设计
### 新增设计组件
1.`designComponents/` 目录下创建组件文件夹
2. 实现 `index.vue``index.json`
3. 自动在 DesignComponentList 中显示
### 功能扩展
1. **拖放后修改源文件** - 通过API将拖放操作写入.vue文件
2. **属性编辑器** - 展示和编辑设计组件属性
3. **热更新同步** - 修改后自动刷新页面
## 总结
本项目实现了一个完整的**Vue页面可视化设计器**通过直接解析和编辑真实的Vue文件实现了低代码的页面构建方式。
**核心亮点**
1. **非侵入式设计** - 通过注入式交互无需修改Vue页面代码
2. **智能层级选择** - 自动识别嵌套结构,键盘切换层级
3. **实时视觉反馈** - 拖拽预览 + 拖放区域指示
4. **结构化路径** - 自动生成可读的元素ID