8.8 KiB
8.8 KiB
Vue页面可视化设计器 - 项目上下文
用途:用于在新环境快速恢复 AI 协作上下文
更新时间:2025-12-22
项目路径:d:/workspace/fauto-design/draggable-panels
📋 项目概述
这是一个基于 Vue3 + TypeScript + Vite + Element Plus 的可视化页面设计器,通过拖拽操作直接编辑真实的Vue页面文件。
核心特性
- 直接解析Vue文件 - 动态扫描并渲染
src/views下的页面 - 拖拽式设计 - 将设计组件拖拽到页面的el-row/el-col上
- 非侵入式交互 - 通过注入方式绑定事件,不修改页面代码
- 智能层级选择 - 键盘方向键切换嵌套元素层级
- 实时视觉反馈 - 拖拽预览 + 拖放区域显示(上/下/左/右)
🏗️ 项目结构
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
示例:
<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>
目的:保证布局可解析性,方便自动生成结构化路径ID
2. 结构化路径ID ⭐
格式:r{n}c{m}r{x}c{y}...
r: el-rowc: el-col- 数字:同级索引(从1开始)
示例:r1c2r1c3 表示:
- 第1个el-row → 第2个el-col → 第1个el-row → 第3个el-col
实现:fauto/plugins/pathUtils.ts
3. 交互事件注入 ⭐
InteractiveWrapper.vue 核心流程:
// 1. 动态渲染组件
<component :is="selectedPageComponent" />
// 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):
// 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. 拖拽交互优化 ⭐
禁用文本选择
// DragPreview.vue
watch(() => dragStore.isDragging, (isDragging) => {
if (isDragging) {
document.body.classList.add('is-dragging')
} else {
document.body.classList.remove('is-dragging')
}
})
/* 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
使用流程
- 点击左侧"页面管理"物料
- 在树形列表中选择一个Vue页面
- 页面在"设计中心"中渲染
- 从"设计组件列表"拖拽组件
- 移动到页面的el-row或el-col上
- 使用↑↓键切换层级
- 点击放置方向(上/下/左/右)
- 查看Footer中的拖放记录
📝 开发规范
创建符合规范的Vue页面
<template>
<!-- 第一层级必须且只能有一个el-row -->
<el-row :gutter="20">
<el-col :span="24">
<!-- 内容 -->
</el-col>
</el-row>
</template>
添加设计组件
- 在
src/fauto/designComponents/下创建目录 - 添加
index.vue和index.json - 自动在列表中显示
插件开发
所有与页面解析、交互相关的代码放在src/fauto/plugins/
🚀 下一步计划
- 拖放后修改源文件 - 通过API将操作写入.vue文件
- 属性编辑器 - 展示和编辑组件属性
- 热更新同步 - 修改后自动刷新页面
- 撤销/重做 - 操作历史记录
📚 相关文档
- 详细设计文档:
项目设计文档.md - 技术选型:Vue3 + TypeScript + Element Plus + Pinia
- 构建工具:Vite 7.3.0
💡 核心创新点
- 非侵入式设计 - 无需修改Vue页面代码即可实现拖拽设计
- 智能层级选择 - 自动识别嵌套结构,精准定位目标位置
- 实时视觉反馈 - 完善的拖拽交互体验
- 结构化路径 - 人类可读的元素定位方式
最后更新:2025-12-22
AI协作建议:优先阅读本文档的"核心技术要点"部分,理解项目的设计理念和实现方式