Skip to content
目录

Editor 模型与 api/tf 分层设计

1. 先说结论

Plate 在近几次核心演进里,把编辑器方法系统性分离为:

  • editor.api:查询/判定/只读能力
  • editor.tf(或 editor.transforms):状态变更能力

这不是“命名美化”,而是为了可维护和可扩展的接口治理。

2. 证据:迁移文档对动机写得很直白

docs/migration/v48.mdx@udecode/plate-core@42.0.0 明确解释:

  • 顶层挂太多方法会污染 editor 接口
  • Slate 本身 transform 分散在多处,认知成本高
  • 重组到 api/tf 后,便于未来 transform middleware、override 机制

文档原话核心意思:这是 DX 和未来扩展能力的结构性优化。

3. 源码落地

withSlate 中,editor 初始化时会注入:

  • editor.getApi
  • editor.getTransforms
  • editor.getPlugin
  • editor.getOption/setOption/setOptions

路径:packages/core/src/lib/editor/withSlate.ts

PlateEditor 类型也同步体现这个结构:

  • packages/core/src/react/editor/PlateEditor.ts

4. 这个分层如何提升插件开发体验

4.1 override 更清晰

当你写:

  • overrideEditor(({ tf: { deleteForward }, api: { isInline } }) => ...)

你能一眼分辨“读”与“写”的边界,避免把查询和变更混在一个对象上。

4.2 类型系统更稳定

插件通过 PluginConfig<key, options, api, transforms, selectors> 分别声明能力域,类型推导更精准。

4.3 中间件化空间更大

Transform 可单独扩展、拦截、包裹,这是后续优化链路(例如规则管线、AI 变更批处理)的基础。

5. 典型延伸追问:为什么不直接沿用 Slate 顶层方法?

推荐回答:

  1. Slate 顶层方式历史兼容强,但规模化插件系统里可读性下降
  2. Plate 通过 api/tf 显式表达职责,降低大型项目认知负担
  3. 保留向后兼容的同时,逐步把“新能力”放到分层接口,属于演进式重构

6. 与插件规则系统的关系

rules(break/delete/merge/selection)最终很多会落到 transforms 执行。tf 分层让这些策略可替换、可组合,而不是散落在编辑器顶层魔法方法里。

小结

api/tf 分层是 Plate 的核心设计支点之一:它把“编辑器能力”从“历史对象结构”升级为“可长期演进的模块化接口”。

MIT License.