## 存档里的一大半是运行时内部状态 画布上的 node 是 vue-flow 的 GraphNode,除了我们自己塞的字段,还挂着 `dimensions` / `computedPosition` / `handleBounds` / `selected` / `dragging` / `resizing` / `initialized` / `isParent` / `events`(见 vue-flow 的 parseNode)。 这些会跟着一起写进 localStorage、进 20 份历史快照被反复深拷贝、还压缩后提交进 数据库**长期存着**。而重新挂载时它们全都会被重新算一遍 —— 存下来没有任何意义, 还把存档格式和 vue-flow 的内部实现绑死了,将来升级或迁移数据都得跟着动。 `handleBounds` 尤其占地方:一个循环节点有 4 个 handle,每个 6 个数字。 抽一个 `serialize.ts`,落盘/入历史/提交前统一裁成 id / type / position / data / style 五个字段。`style` 保留 —— 它是建节点时按类型算好的,丢了恢复出来的图会变样。 实测:一个两节点带连线的图,存档 600 字节、节点上只剩那五个字段,九个内部字段 一个不剩;提交上去压缩后 396 字节。 ## Ctrl+Y 是假的 工具栏按钮的 title 写着「重做 (Ctrl+Y)」,但只实现了 Ctrl+Shift+Z,按 Y 没反应。 顺手把 key 比较改成小写不敏感(按住 Shift 时 event.key 是大写的 "Z")。 ## 清空画布点一下就没了 那个按钮不但清空画布,`clearCache()` 还会把这道题存着的草稿一起删掉,刷新也找 不回来。学生误点的代价太大,加一道确认;画布本来就是空的时候不弹。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
oj.xuyue.cc