← 全部文章

技术笔记 · 2026-09-14

虚拟表格滚动后,编辑状态应该保存在哪里

从 ERP 大表格场景分析行节点复用:用稳定行标识管理草稿、校验和焦点,避免滚动、排序与刷新让编辑内容串行或丢失。

延伸分析 · 从项目场景展开的原理与方案讨论。

  • 虚拟列表
  • 表格编辑
  • 状态管理
  • 稳定标识

关联项目:企业 ERP 管理系统。项目资料包含虚拟化表格应用。本文进一步分析可编辑虚拟表格的状态归属,不代表原项目采用了文中的全部设计。

行离开视口,业务状态不该随之消失

虚拟化只渲染可见区域附近的行,可以减少 DOM 数量。但用户正在编辑的记录即使滚出了屏幕,它的草稿、错误和保存结果仍然存在。

若把草稿仅放在单元格组件的局部状态中,组件卸载就可能丢失修改;如果节点被复用给另一条记录,又可能把上一行的输入带过去。优化渲染数量之后,还要重新划清状态生命周期。

记录身份不能跟着数组位置变化

排序和筛选会改变下标。应让记录 ID、列标识共同决定一个单元格的业务身份,例如 rowId + columnKey,而不是“当前第 5 行”。

虚拟化库也需要稳定标识才能关联测量和节点。TanStack Virtual 的 getItemKey 文档可以作为 API 设计参考;这里并不表示 ERP 项目使用了该库。

把编辑状态放在渲染窗口之外

可以按职责保存几份状态:

状态 建议身份 作用
服务端记录 rowId 最近确认的数据和版本
本地草稿 rowId、columnKey 尚未提交的输入
校验错误 rowId、columnKey 随滚动继续保留的反馈
活动单元格 rowId、columnKey 重新进入视口时恢复交互

单元格挂载后读取自己的草稿,输入时更新草稿容器。展示窗口变化只改变哪些控件存在,不直接决定哪些修改有效。

这不等于要把所有数据塞进全局 store。状态放在表格或编辑任务的生命周期内即可;离开页面是否保留,应由产品交互决定。

数据刷新不能无条件覆盖草稿

服务端刷新到来时,未编辑字段可以更新;已有草稿的字段需要保留用户输入,或者提示服务端值发生变化。保存时若要检测并发覆盖,需要后端提供版本校验等契约,前端的 dirty 标记本身不能防止丢失更新。

记录被删除、权限变化和保存失败也不应靠组件销毁“自动解决”。这些状态需要一个可见的处理入口,用户才能决定重试、放弃或重新读取。

焦点恢复也依赖记录身份

按键移动到尚未渲染的行时,先请求虚拟列表让目标进入渲染范围,等待节点可用后再聚焦。恢复任务必须验证目标仍是当前活动单元格,避免快速移动后旧任务抢回焦点。

不能长期保存一个 DOM 引用,假设它始终代表同一条记录。

滚动性能之外的验收

输入未保存内容,滚出视口再回来;随后排序、筛选、刷新和删除记录,确认草稿始终属于原记录。再覆盖异步校验返回、保存失败以及键盘导航。

虚拟化解决“同时渲染多少行”。编辑模型解决“每次修改属于谁、何时生效”。两者分开,才能兼顾性能与正确性。