hi, 大家好, 我是徐小夕.
之前和大家分享了我实现的 pxcharts 多维表格技术方案:
pxcharts-pro, 支持百万数据渲染的多维表格编辑器
最近研究了在线协同 功能,花了大概半年时间,研究文档引擎和协同算法,最近终于实现了一个毫秒级文档协同编辑器,媲美企业级协同应用,接下来就和大家分享一下这款文档编辑器。

演示地址:px-doc 协同文档编辑器
先来聊聊协同算法的实现方案

上面是我整理的一个协同方案实现的核心逻辑层,目前我采用CRDT 的方案来实现,这里就简单和大家聊聊CRDT算法的作用:
- 分布式冲突消解:每个客户端通过本地 CRDT 引擎独立处理操作,无需依赖服务端 "中心化仲裁",并发操作通过 "唯一操作 ID" 和 "版本向量" 自动合并(如 A 插入文本、B 同时删除相邻文本,CRDT 按时序和操作属性判断优先级,避免文档错乱)。
- 离线编辑支持:客户端断网时,CRDT 引擎缓存本地操作日志;重连后自动同步离线操作到服务端,服务端广播给其他客户端,最终所有终端收敛到一致状态,无需用户手动合并。
- 低延迟编辑体验:操作生成后先更新本地 UI,再异步同步到其他端,用户无 "等待锁释放" 的阻塞感,编辑流畅性接近本地文档。
(当然协同方案也可以采用OT算法架构来实现)接下来我们再来聊聊我做的协同文档编辑器。
px-doc协同文档编辑器介绍
我在协同文档编辑器中实现了非常复杂的功能,比如可视化图表,音视频组件,移动端适配,版本管理等:

由于国内企业用Vue的比较多,所以文档编辑器我采用了Vue3的实现方案,当然React也能实现同样的协同能力。
1. 技术实现
- 前端框架 Vue 3(组合式 API)
- 选择原因:生态成熟、类型友好、与 Vite 深度集成、上手与维护成本低。
- 构建与开发 Vite 5、UnoCSS、Sass、ESLint + Prettier
- 选择原因:Vite 冷启动快、按需插件丰富;UnoCSS 原子化样式灵活;Sass 提升样式工程化;统一的 Lint/Format 保证一致性。
- 路由与状态 Vue Router 4、Pinia
- 选择原因:与 Vue 3 官方生态一致,路由/状态管理简单直观、可维护性高。
- 协同内核 CRDT算法
- 选择原因:CRDT 协同模型成熟、离线同步稳定;轻量易部署,具备断线重连能力。
- UI 与交互 Arco Design Vue、Tippy、@floating-ui
- 选择原因:企业级组件库与工具链完善,易于定制;浮层定位交互稳定。
- 数据请求 Axios(封装于
@/utils/req
)- 选择原因:请求拦截、错误处理统一;易扩展 Token、语言包等。
- 国际化与工具 vue-i18n、@vueuse/core、lodash、uuid
- 选择原因:提升 DX 与功能实现效率。
- 可选可视化 ECharts(图表扩展)
- 选择原因:在编辑器内插入图表或渲染统计内容。
- 后端(外部服务) 文件持久化(JSON)、分布式协同服务
- 选择原因:以文件存储快速落地,便于后续平滑迁移至数据库;协同通道与编辑态解耦。
2. 架构设计
系统采用"前后端分离 +CRDT 实时协同 + 文件持久化"的轻量架构:
- 前端应用(SPA)
-
- 入口:
src/main.js
→ 挂载App.vue
,引入路由、Pinia、样式。 - 路由守卫:
src/router/index.js
,基于localStorage.uid
的简易登录态;未登录跳转login
。 - 编辑器页:
src/views/doc-page/doc-page.vue
(Notion 风格),集成协同逻辑、版本面板。 - 版本面板:
src/components/VersionManager.vue
,支持版本列表、预览、恢复、删除与信息编辑。
- 入口:
- 协同层
-
- CRDT协同机制作为单一事实源(Single Source of Truth),通过
websocket
与服务器保持实时同步。
- CRDT协同机制作为单一事实源(Single Source of Truth),通过
- 后端服务(外部)
-
- 文档列表:
server/db/document/documents.json
- 版本记录:
server/db/version/<docId>.json
- 文档列表:
-
- 文档/版本元数据使用文件系统持久化:
- 协同内容建议启用
.crdt
文件持久化(CRDT 序列化),提升容灾与重启恢复能力。
- 静态资源与构建
-
- 通过 Vite 构建,产物输出至
px-editor/
(vite.config.js
中build.outDir
)。 - 生产环境通过
BASE_API_URL/BASE_WS_URL
切换接口与协同服务地址。
- 通过 Vite 构建,产物输出至
3. 功能亮点与场景

接下来就我实现的文档协同编辑器,总结以下几点优势:
- 多人实时协同编辑 (CRDT协同算法)
- 支持光标与选区显示、低延迟同步、离线/重连状态的自动合并。
- 适用于团队文档、产品需求、方案评审等实时协作场景。
- 版本管理全流程 (列表/创建/删除/预览/恢复/自动保存)
- 评审前生成"稳定版本",评审后可快速回滚。
- 线上服务重启后,客户端自动恢复到最后可用内容。
- 版本列表分页展示,包含作者、时间、大小、类型(自动/手动)。
- 只读 Doc 实例渲染版本内容,预览接近真实排版。
- 自动恢复:协同连接完成且文档为空时,自动加载"最近版本"。
- 使用案例:
- 文件解析与导入 (进行中)
- 提供
/parse/doc2html2
与/parse/pdf2html
的上传/分页获取接口。 - 适用于将历史文档、合同、报告转入协同编辑流程。
- 提供
- 可插拔扩展体系 (Doc Extensions + Vue 组件)
- 富文本、表格、任务清单、图表、代码高亮等扩展可按需启用。
- 支持 Notion 风格工具栏/菜单、Bubble Menu、Slash Menu。
4. 二次开发指南
整个编辑器我采用模块化的开发方式,我们可以轻松采用组件化的方式集成到系统中。
4.1 代码结构总览
shell
src/
api/# 文档/版本/文件解析等接口封装
components/# 版本面板等复用组件
packages/# 编辑器核心与扩展(core/vue3)
router/# 路由与守卫
stores/# Pinia 状态(示例)
styles/# 全局样式(Sass + UnoCSS)
utils/# 请求封装、工具函数
views/# 页面(login / doc-page)
关键文件:
src/main.js
应用入口,注册 Pinia、Router。src/router/index.js
路由表与鉴权守卫。src/api/document.ts
、src/api/version.ts
、src/api/file.ts
:HTTP API 封装。src/packages/vue3/editor.js
、src/packages/core/*
:编辑器与扩展能力。src/components/VersionManager.vue
版本列表、预览与恢复。
4.2 开发环境搭建
-
安装依赖
pnpm install
-
启动前端(默认 http://localhost:9999)
pnpm dev
-
启动服务端(示例,按你的实际脚本为准)
bash
npm start
# 或 Windows: npm run start:win
演示地址:px-doc 协同文档编辑器
后续我会持续迭代协同文档编辑器,并持续优化性能和功能,大家有好的想法也欢迎随时交流反馈.