news 2026/6/14 6:55:18

Yjs 前端实时协作库学习笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Yjs 前端实时协作库学习笔记

核心定位

纯前端 / Node.js 通用的实时协作数据一致性库,基于 CRDT(无冲突复制数据类型)实现,核心解决「多人同时修改数据、断网离线修改数据」后的数据自动统一问题,是前端开发在线文档、白板、表格等协作类应用的核心工具,也是 BlockSuite 实时协作能力的底层内核。

简单说:给普通 JS 数据加「协作外挂」,改数据时自动同步、自动解决冲突,开发者不用写分布式、冲突解决、数据同步的代码,专注业务即可。

一、核心特性(大白话版)

  1. CRDT 底层,无需服务端强同步:每个客户端存一份完整数据副本,冲突本地自动计算,最终所有设备数据一致;对比 OT 技术,不用服务端做复杂操作转换,开发更简单。
  2. 兼容前端常用数据类型:支持数组、键值对、树形结构等,操作方法和普通 JS 数据几乎一致,低成本替换原有数据。
  3. 通信完全解耦:只负责「生成同步的小数据片段」,不管「数据怎么传」,WebSocket、WebRTC、小程序通信等都能适配。
  4. 原生支持离线编辑:自动将数据存在浏览器 IndexedDB,断网修改不丢失,联网后自动重连并同步本地修改。
  5. 前端无缝集成:TS/JS 原生支持,体积小,和 Vue/React/ 原生前端、Web Components 都能完美搭配。

二、核心依赖安装

bash

运行

# 核心库(必须装) npm install yjs # 官方 WebSocket 通信插件(快速实现多人协作,无需自己开发服务端,推荐必装) npm install y-websocket

三、核心概念(3 个核心,记牢即可)

1. Y.Doc - 共享数据容器

所有 Yjs 共享数据的根容器,是协作的核心入口。

  • 每个协作文档对应一个唯一标识,不同客户端用相同标识就能同步数据;
  • 每个客户端都要创建一份 Y.Doc,内部维护分布式共享数据。

2. 共享数据类型 - 替换普通 JS 数据

Yjs 提供专属的「共享数据类型」,替换原有 JS 数组 / 对象 / 树,操作方法几乎一致,修改后会自动标记同步片段。

Yjs 共享类型对应普通 JS 类型适用场景
Y.Array数组存列表数据(如 BlockSuite 块列表)
Y.Map对象 / Map存键值对数据(如用户信息、块属性)
Y.XmlFragment/Y.XmlElement树形结构存层级数据(如 BlockSuite 块树、富文本节点)

3. observe - 数据变化监听

监听共享数据的所有修改(本地修改 / 远端协作方修改都会触发),是「数据驱动视图」的核心,通过监听事件实现视图精准更新。

四、核心代码片段(极简实用,直接复制可运行)

片段 1:基础使用 - 创建共享数据 + 本地修改监听

实现普通 JS 数据的「共享化」,掌握基础的增删改和监听逻辑。

javascript

运行

import * as Y from 'yjs'; // 1. 创建共享文档容器 const yDoc = new Y.Doc(); // 2. 创建共享数据(替换普通 JS 数组/Map) const yArr = yDoc.getArray('myList'); // 共享数组 const yMap = yDoc.getMap('myInfo'); // 共享键值对 // 3. 监听数据变化(本地/远端修改统一触发) yArr.observe((event) => { console.log('数组数据变化:', event); console.log('最新数组(转普通 JS):', yArr.toArray()); // 转普通 JS 供视图渲染 }); // 4. 操作共享数据(和普通 JS 用法几乎一致) yArr.push(['苹果', '香蕉']); // 新增元素 yArr.set(0, '红苹果'); // 修改元素 yMap.set('author', '张三'); // Map 设值 // 5. 转换为普通 JS 数据(视图渲染专用,Yjs 数据不能直接绑视图) console.log(yArr.toArray()); // ['红苹果', '香蕉'] console.log(yMap.toJSON()); // { author: '张三' }

片段 2:多人协作核心 - WebSocket 通信桥接

3 行代码实现多端同步,不用自己开发服务端,打开多个浏览器窗口即可测试协作效果。

javascript

运行

import * as Y from 'yjs'; import { WebsocketProvider } from 'y-websocket'; // 1. 创建共享文档 const yDoc = new Y.Doc(); const yArr = yDoc.getArray('collabList'); // 2. 连接官方测试服务端(一键实现通信,无需自己搭服务) // 格式:WebsocketProvider(服务端地址, 协作文档唯一标识, Yjs文档) const provider = new WebsocketProvider( 'wss://demos.yjs.dev', // Yjs 官方免费测试服务端 'my-first-collab-doc', // 同一协作文档用相同标识,不同客户端自动同步 yDoc ); // 3. 监听协作连接状态(可选,做加载/离线提示) provider.on('status', (event) => { console.log('协作连接状态:', event.status); // connected / disconnected / connecting }); // 4. 任意客户端修改,其他客户端实时同步 yArr.push(['协作数据1', '协作数据2']);

片段 3:精准监听 - 增 / 删 / 改单独处理(适配视图精准更新)

实际开发无需全量渲染视图,通过 Yjs 事件精准获取「哪里变了、变了什么」,实现 BlockSuite 同款「精准视图更新」。

javascript

运行

import * as Y from 'yjs'; const yDoc = new Y.Doc(); const yBlocks = yDoc.getArray('blocks'); // 模拟 BlockSuite 块列表 // 精准监听数组的增、删、改 yBlocks.observe((event) => { // 1. 新增元素:[索引, 元素值] event.changes.added.forEach(([index, value]) => { console.log(`索引${index}新增:`, value); // 业务操作:新增对应视图节点(如 BlockSuite 新增块) }); // 2. 更新元素:仅返回索引,值从 yBlocks.get(index) 获取 event.changes.updated.forEach((index) => { const updateValue = yBlocks.get(index); console.log(`索引${index}更新为:`, updateValue); // 业务操作:更新对应视图节点(精准渲染) }); // 3. 删除元素:[索引, 被删值] event.changes.deleted.forEach(([index, value]) => { console.log(`索引${index}删除:`, value); // 业务操作:删除对应视图节点 }); }); // 测试操作(分别触发 added/updated/deleted) yBlocks.push([{ id: '1', content: '测试块1' }]); yBlocks.set(0, { id: '1', content: '修改后的块1' }); yBlocks.delete(0);

片段 4:离线编辑 + 自动重连(原生支持,无需额外代码)

Yjs 自动将数据存在浏览器 IndexedDB,断网修改不丢失,联网后自动同步,全程无需自己写本地存储、重连逻辑。

javascript

运行

import * as Y from 'yjs'; import { WebsocketProvider } from 'y-websocket'; const yDoc = new Y.Doc(); const yArr = yDoc.getArray('offlineList'); const provider = new WebsocketProvider('wss://demos.yjs.dev', 'offline-doc', yDoc); // 断网后:正常修改数据,自动存在本地 IndexedDB yArr.push(['断网编辑的内容1', '断网编辑的内容2']); // 联网后:自动重连,将本地修改同步给服务端/其他客户端,无需额外代码

片段 5:树形结构使用(和 BlockSuite 块树深度适配)

BlockSuite 的「块树」是核心,Yjs 用Y.XmlFragment/Y.XmlElement实现分布式树形结构,完美贴合块的父子层级关系。

javascript

运行

import * as Y from 'yjs'; const yDoc = new Y.Doc(); // 创建共享树形结构(模拟 BlockSuite 根块树) const yBlockTree = yDoc.getXmlFragment('blockTree'); // 1. 创建块节点(设置块类型、属性) const titleBlock = Y.XmlElement('text'); // 节点类型=块类型(text/Image/table) titleBlock.setAttribute('id', 'title1'); // 块唯一ID titleBlock.setAttribute('content', 'BlockSuite 标题块'); // 块内容 const contentBlock = Y.XmlElement('text'); contentBlock.setAttribute('id', 'content1'); contentBlock.setAttribute('content', 'BlockSuite 内容块'); // 2. 构建父子层级(标题块为父,内容块为子) titleBlock.insertChild(0, contentBlock); // 3. 将根节点加入块树 yBlockTree.insertChild(0, titleBlock); // 4. 监听树变化(精准到节点增删、属性修改) yBlockTree.observe((event) => { console.log('块树变化:', event); }); // 这是 BlockSuite 块树的底层实现:基于 Yjs 树形结构做分布式共享

五、Yjs 在 BlockSuite 中的核心应用

BlockSuite 把 Yjs 作为内核数据引擎,而非简单第三方依赖,核心结合点:

  1. 块数据共享化:所有块(文字 / 图片 / 表格)的属性、层级关系,都存在 Yjs 共享数据中(数组 / 树形结构);
  2. 操作标准化:BlockSuite 的 Command 命令修改块数据时,实际是修改 Yjs 共享数据,Yjs 自动生成同步片段;
  3. 统一视图更新:BlockSuite 仅监听 Yjs 数据变化,不区分修改来自「本地」还是「远端协作方」,统一触发视图精准更新;
  4. 协作通信解耦:BlockSuite 封装了 Yjs 通信接口,支持替换 WebSocket/WebRTC 等通信方式,适配不同协作场景。

六、关键总结(核心考点 / 开发要点)

  1. Yjs 核心作用:解决前端多人协作的数倨一致性,自动同步、自动解决冲突,离线编辑原生支持;
  2. 开发核心流程:创建 Y.Doc → 定义共享数据 → 监听数据变化驱动视图 → 配置通信插件实现多端同步;
  3. 核心优势:操作简单(和普通 JS 数据用法几乎一致)、视图友好(精准监听变化,支持按需渲染)、扩展灵活(通信层可自由替换);
  4. 和 BlockSuite 关系:Yjs 是 BlockSuite 实时协作的底层数据基础,BlockSuite 基于 Yjs 封装了块模型、命令系统,实现了「块式编辑 + 实时协作」的融合。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/7 4:46:36

实测缩短70%课件制作时间:这款AIPPT工具就是老师的大救星

实测缩短70%课件制作时间:ChatPPT引领教学效率革命 实测数据显示,使用ChatPPT制作课件,基础构建时间可缩短70%以上,这不是夸张,而是众多教育工作者的真实反馈。在2026年的今天,课件制作正经历着一场由AI驱动…

作者头像 李华
网站建设 2026/6/5 15:53:29

CoDeSys入门实战一起学习(二十):布尔、整型、实数、字符串、时间5大类标准数据类型详解(附实战案例)

写CoDeSys程序的第一步,必然是声明变量/常量,而所有声明都离不开数据类型。CoDeSys的标准数据类型完全遵循IEC61131-3标准,共分为布尔、整型、实数、字符串、时间5大类,是所有PLC程序的“基础积木”。很多新手容易踩坑&#xff1a…

作者头像 李华
网站建设 2026/6/8 10:28:49

KingbaseES数据库瓶颈排查实战指南:从实例到语句的全维度解析

在高并发、海量数据的业务场景下,数据库性能直接决定了应用系统的响应速度和稳定性,而瓶颈排查则是性能调优的核心前提——只有精准定位问题根源,才能避免盲目调参、优化无效的内耗。KingbaseES作为国产数据库中的优秀代表,在政务…

作者头像 李华
网站建设 2026/6/10 15:00:00

巡防勤务可视化管理

巡防勤务可视化管理 巡防勤务管理可视化系统,基于大数据平台的警务地理信息系统,可以实时查看警力在岗状态、警力分布、应急资源等。系统支持快速定位警员、车辆的位置,查看警力详细信息,调取监控视频画面,并进行单方…

作者头像 李华
网站建设 2026/6/14 5:53:09

想把网页保存成PDF文件,快速删掉侧边栏广告再打印

想要把网页保存成PDF文件的时候经常会有右侧左侧侧边栏挡住主要内容。怎么办呢? 打开 开发者模式 在 console 里粘贴以下,回车,就好了! // 隐藏所有可能包含侧边栏的常见元素 var style document.createElement(style); style.in…

作者头像 李华
网站建设 2026/6/11 4:57:47

深度学习之第八课迁移学习(残差网络ResNet)

目录 简介 一、迁移学习 1.什么是迁移学习 2. 迁移学习的步骤 二、残差网络ResNet 1.了解ResNet 2.ResNet网络—残差结构 三、代码分析 1. 导入必要的库 2. 模型准备(迁移学习) 3. 数据预处理 4. 自定义数据集类 5. 数据加载器 6. 设备配置 7. 训练函数 8. 测…

作者头像 李华