Vue Flow 前端图编辑器与 YAML 双向同步
Vue Flow 前端图编辑器与 YAML 双向同步
学习目标
- 理解 ChatDev 前端的技术栈与架构
- 掌握 @vue-flow 图可视化框架的集成方式
- 了解 YAML ↔ 图形的双向转换流程
- 理解
make sync命令的作用与实现
项目实践
前端技术栈
{ "dependencies": { "@vue-flow/background": "^1.3.2", "@vue-flow/controls": "^1.1.3", "@vue-flow/core": "^1.47.0", "@vue-flow/minimap": "^1.5.4", "js-yaml": "^4.1.0", "markdown-it": "^14.1.0", "vue": "^3.5.22", "vue-i18n": "^11.3.0", "vue-router": "^4.6.0" }}核心技术选型:
| 库 | 用途 |
|---|---|
| Vue 3 | 响应式前端框架 |
| @vue-flow | 图可视化(节点、边、拖拽) |
| js-yaml | YAML 解析与序列化 |
| vue-router | 前端路由 |
| vue-i18n | 国际化(中英文切换) |
| markdown-it | Markdown 渲染(日志、输出) |
前端目录结构
frontend/src/├── main.js # Vue 应用入口├── App.vue # 根组件├── router/ # Vue Router 配置├── pages/ # 页面组件├── components/ # 通用组件├── i18n.js # 国际化配置├── locales/ # 多语言文件├── utils/ # 工具函数├── assets/ # 静态资源└── style.css # 全局样式YAML → 图形转换
转换规则:
YAML Node → Vue Flow Node id → id type → node type (custom node renderer) config.name → label position → auto-layout 或手动指定
YAML Edge → Vue Flow Edge from → source to → target condition → edge style (实线/虚线/颜色)图形 → YAML 转换
用户在编辑器中拖拽节点、连线后,图形序列化为 YAML:
Vue Flow Nodes → { id, type, config, position }Vue Flow Edges → { from, to, condition, carry_data } ↓组装为 graph 对象 ↓js-yaml.dump() → YAML 字符串 ↓POST /api/workflows → 保存到后端make sync 命令
make sync功能:将 yaml_instance/ 中的所有 YAML 工作流文件上传到数据库,使前端可以看到最新的模板。
实现:
sync: uv run python -c "..." # 调用后端 API 批量上传这与前端的图形编辑互补:
- make sync:文件 → 数据库(批量导入)
- 图形编辑:数据库 → 前端 → 修改 → 保存回数据库
问题与规避
| 问题 | 表现 | 规避策略 |
|---|---|---|
| YAML 解析错误 | 缩进不正确导致解析失败 | 先用 make validate-yamls 静态检查 |
| 大图渲染卡顿 | 节点过多导致浏览器性能下降 | 虚拟滚动 + 节点懒加载 |
| 自动布局冲突 | 节点位置重叠 | 使用 @vue-flow 的 layout 插件 |
| YAML 版本不兼容 | 前端 Schema 与后端不同步 | 通过 API 动态获取 Schema |
| 国际化缺失 | 新增文本未翻译 | 确保所有用户可见文本都有 i18n key |
设计取舍
@vue-flow vs 自研 Canvas
| 维度 | @vue-flow | 自研 Canvas |
|---|---|---|
| 开发成本 | 低(开箱即用) | 高(从零实现) |
| 定制能力 | 中(受限于 API) | 高(完全可控) |
| 社区生态 | 大(Vue 生态插件) | 无 |
| ChatDev 的选择 | ✅ 使用 | ❌ 未采用 |
js-yaml vs 后端序列化
ChatDev 在前端使用 js-yaml 而非依赖后端序列化:
- 优势:前端离线编辑、减少 API 调用
- 代价:前后端 YAML 解析器可能行为不一致