# Vue页面可视化设计器 - 项目设计文档 ## 1. 项目概述 本项目是一个基于 **Vue3 + TypeScript + Element Plus** 的可视化页面设计器,通过拖拽操作直接编辑真实的Vue源文件,实现低代码页面快速构建。 ### 1.1 核心特性 | 特性 | 描述 | |------|------| | 直接解析Vue文件 | 动态渲染真实的.vue页面 | | 源码级修改 | 拖拽操作直接修改Vue源文件 | | 智能层级选择 | 键盘方向键切换嵌套元素层级 | | 元数据编辑 | 可视化编辑组件属性 | | 多视图联动 | 设计中心、结构树、元数据面板同步选中 | | 热更新 | 修改后自动刷新预览 | ### 1.2 技术架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 前端应用 (Vue3 + Vite) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 页面管理 │ │设计组件列│ │ 设计中心 │ │ 元数据 │ │ │ │ │ │表 │ │ │ │ 编辑器 │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ Pinia 状态管理 + 插件系统 │ │ │ │ dragStore │ interactionStore │ designStore │ vueFileStore│ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ HTTP API ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 后端服务 (Node.js + Express) │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ templateService - Vue模板AST解析与修改 │ │ │ │ @vue/compiler-sfc + @vue/compiler-dom │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ 文件操作 ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Vue源文件 (src/views/*.vue) │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## 2. 核心模块设计 ### 2.1 前端模块 #### 2.1.1 设计中心 (DesignCenter) **职责**:动态渲染选中的Vue页面,注入交互事件 **核心组件**: - `index.vue` - 主容器,动态加载Vue页面组件 - `InteractiveWrapper.vue` - 交互包装器,注入事件监听 - `DropZone.vue` - 拖放区域指示器 - `DragPreview.vue` - 拖拽跟随预览 **交互事件注入流程**: ```typescript // 1. 动态渲染页面组件 // 2. 挂载后扫描DOM,注入事件 const injectInteractionEvents = () => { document.querySelectorAll('.el-row, .el-col').forEach(el => { const path = generateElementPath(el) // 生成结构化路径 bindElementEvents(el, type, path) // 绑定交互事件 }) } // 3. MutationObserver监听DOM变化,动态注入 observer.observe(container, { childList: true, subtree: true }) ``` #### 2.1.2 结构树 (TreeViewer) **职责**:展示页面的el-row/el-col结构,支持选中和删除 **功能**: - 树形展示页面结构 - 点击节点选中对应元素 - 拖拽节点调整顺序 - 右键菜单/删除图标/Del键删除 #### 2.1.3 元数据编辑器 (DataTable) **职责**:展示和编辑选中组件的属性 **支持的属性类型**: - `number` - 数字输入(如span宽度) - `text` - 文本输入(如placeholder) - `select` - 下拉选择(如size尺寸) - `boolean` - 开关切换(如stripe斑马纹) - `color` - 颜色选择器 #### 2.1.4 插件系统 (plugins/) **dragStore** - 拖拽状态管理 ```typescript interface DragStore { // 状态 isDragging: boolean dragPhase: 'source' | 'target' // 两阶段拖拽 dragSource: DragSource | null hierarchyNodes: HierarchyNode[] // 层级节点列表 selectedHierarchyIndex: number // 当前选中层级 hoverDirection: Direction | null // 方法 startDragFromCanvas(path, type, element) // 开始画布内拖拽 startDragFromComponentList(id, name, template) // 开始组件列表拖拽 enterTargetPhase(element) // 进入目标选择阶段 selectParentLevel() // 选择父级(↑键) selectChildLevel() // 选择子级(↓键) confirmDrop(pagePath) // 确认拖放 } ``` **interactionStore** - 交互事件钩子 ```typescript interface InteractionStore { hoverTarget: InteractionTarget | null selectedTarget: InteractionTarget | null onHover(target) onClick(target) onLeave() } ``` ### 2.2 后端模块 #### 2.2.1 templateService **职责**:解析Vue文件,执行结构修改 **核心函数**: | 函数 | 功能 | |------|------| | `moveElement(vueContent, options)` | 移动元素到新位置 | | `insertElement(vueContent, options)` | 插入新元素 | | `deleteElement(vueContent, elementPath)` | 删除元素 | | `parseElementTree(vueContent)` | 解析页面结构树 | | `parseComponentProps(vueContent, path)` | 获取组件属性 | | `updateComponentProps(vueContent, path, updates)` | 更新组件属性 | **技术实现**: ```javascript // 使用 @vue/compiler-sfc 解析Vue文件 import { parse as parseSFC } from '@vue/compiler-sfc' // 使用 @vue/compiler-dom 解析template获取AST import { parse as parseTemplate } from '@vue/compiler-dom' // 通过AST定位元素,使用字符串操作修改(保持原始格式) ``` --- ## 3. 数据结构设计 ### 3.1 结构化路径 **格式**:`r{n}c{m}r{x}c{y}...` | 前缀 | 含义 | |------|------| | r | el-row | | c | el-col | | 数字 | 同级元素中的索引(从1开始) | **示例**:`r1c2r1` = 第1个row → 第2个col → 第1个row ### 3.2 设计组件配置 ```json { "id": "TextInput", "name": "输入框", "icon": "✏️", "description": "用于输入文本内容的表单组件", "defaultSpan": 12, "metadata": { "span": { "label": "宽度", "type": "number", "min": 1, "max": 24, "target": "el-col", "attr": ":span" }, "placeholder": { "label": "占位符", "type": "text", "target": "el-input", "attr": "placeholder" } } } ``` ### 3.3 设计组件模板 ```html
``` **关键点**: - 外层必须是 `el-col` - 内层 `div` 必须有 `data-component` 属性标识组件类型 - 使用 `class="design-component"` 标识设计组件 --- ## 4. API设计 ### 4.1 元素操作API #### 移动元素 ``` POST /api/move-element Body: { "pagePath": "D:/workspace/.../TestPage1.vue", "source": { "type": "canvas-element", "path": "r1c1", "elementType": "ec" }, "targetPath": "r1c2", "targetType": "ec", "direction": "right" // top|bottom|left|right|inside } ``` #### 插入元素 ``` POST /api/insert-element Body: { "pagePath": "...", "templateContent": "...", "targetPath": "r1c1", "direction": "right" } ``` #### 删除元素 ``` POST /api/delete-element Body: { "pagePath": "...", "elementPath": "r1c2" } ``` ### 4.2 属性操作API #### 获取组件属性 ``` GET /api/component-props?pagePath=...&elementPath=r1c1 Response: { "success": true, "componentId": "输入框", "props": { "span": 12, "el-input:placeholder": "请输入" } } ``` #### 更新组件属性 ``` POST /api/update-props Body: { "pagePath": "...", "elementPath": "r1c1", "updates": { "span": 8, "el-input:placeholder": "新占位符" } } ``` ### 4.3 结构查询API #### 获取页面结构树 ``` GET /api/element-tree?pagePath=... Response: { "success": true, "tree": [ { "type": "row", "path": "r1", "label": "el-row", "children": [ { "type": "col", "path": "r1c1", "componentName": "输入框", "children": [] } ] } ] } ``` --- ## 5. 交互设计 ### 5.1 拖拽流程 ``` 1. 用户开始拖拽(组件列表/画布元素) ↓ 2. 进入源选择阶段,收集层级节点 ↓ 3. 移动到目标位置,进入目标选择阶段 ↓ 4. 显示DropZone(上/下/左/右/放入) ↓ 5. 用户点击方向确认拖放 ↓ 6. 调用后端API修改源文件 ↓ 7. 触发vue-template-updated事件 ↓ 8. 前端刷新页面和结构树 ``` ### 5.2 层级选择 当鼠标悬停在嵌套元素上时(如`r1c1r1c1`): - **默认选中**:最深层级(r1c1r1c1) - **↑键**:切换到父级(r1c1r1 → r1c1 → r1) - **↓键**:切换到子级 - **Esc**:取消拖拽 ### 5.3 多视图联动 - 点击**设计中心**元素 → 结构树高亮 + 元数据面板更新 - 点击**结构树**节点 → 设计中心高亮 + 元数据面板更新 - **元数据面板**修改 → 源文件更新 → 设计中心刷新 --- ## 6. 扩展指南 ### 6.1 添加设计组件 1. 在 `src/fauto/designComponents/` 创建目录 2. 添加 `index.json`(配置+元数据schema) 3. 添加 `template.html`(组件模板) 4. 自动在组件列表显示 ### 6.2 添加物料组件 1. 在 `src/fauto/materials/` 创建目录 2. 添加 `index.vue`(组件实现) 3. 添加 `index.json`(配置信息) 4. 在 `materials/index.ts` 注册 ### 6.3 扩展元数据类型 在 `designStore.ts` 的 `MetadataField` 接口添加新类型,并在 `DataTable/index.vue` 添加对应的编辑控件。 --- ## 7. 技术规范 ### 7.1 Vue页面规范 ```vue ``` ### 7.2 代码规范 - TypeScript 严格模式 - Composition API 组织代码 - Props 必须定义类型 - 样式使用 scoped - 插件代码放 `fauto/plugins/` --- ## 8. 版本信息 - **前端框架**: Vue 3.5.24 - **构建工具**: Vite 7.3.0 - **状态管理**: Pinia 3.0.4 - **UI框架**: Element Plus - **后端运行时**: Node.js - **模板解析**: @vue/compiler-sfc, @vue/compiler-dom --- **文档更新时间**:2026-01-20