大家好,我是前端西瓜哥。
创新互联公司服务项目包括新蔡网站建设、新蔡网站制作、新蔡网页制作以及新蔡网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,新蔡网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到新蔡省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
为了测试 Yjs 的协同能力,我实现了支持协同简单的 TODO 应用。
列一下用到的技术:
源码放 Github 上了。因为花了一天写的简易 Demo,没有太分模块,代码很稀烂,仅供参考。
https://github.com/F-star/yjs-react-todo-app。
先安装依赖:
pnpm install
然后两个终端分别启动服务端和客户端:
pnpm run server
pnpm run dev
简单看看效果。
创建一个房间。
复制这个房间链接,在另一个浏览器里打开。
然后就是一段操作。
所有的需要同步的对象都保存在一个 Y.Doc 对象下,在其下会创建 Yjs 的数据类型,比如 YArray、YMap。
this.ydoc = new Y.Doc();
然后我们需要一个 Provider 去将这个对象的内容同步出去,以及同步回来。
this.provider = new WebsocketProvider(wsUrl, this.roomId, this.ydoc);
模块之间的解耦,果然还得是发布订阅模式。通过 observer 监听数据的变化,然后同步到组件上。
// 创建顶层的 YArray 对象
this.yTodoItems = this.ydoc.getArray('todoItems');
this.yTodoItems.observe(callback);
// 拿到 YArray 对应的普通数组对象,更新组件的内部状态
yjsClient.onTodoItemsChange((event) => {
setTodoItems(event.target.toArray());
});
对于要修改一个 YArray 下一个普通对象的情况,不能修改这个普通对象的属性,它不会触发 observe 事件。我们有两种解法。
第一种方案是从 YArray 对象下删除对应索引位置的对象,然后在这个地方再插入一个修改了属性的拷贝对象。
toggleTodoItemDone(index: number) {
// 下面的写法无法触发 observe
// const item = this.yTodoItems.get(index);
// item.done = !item.done;
// 下面的写法可以触发 observe
const item = this.yTodoItems.get(index);
this.yTodoItems.delete(index, 1);
this.yTodoItems.insert(index, [
{
id: item.id,
text: item.text,
done: !item.done,
},
]);
}
第二种方案是可以将这个普通对象换成 Y.Map 对象嵌入 YArray 下,通过它的 API 修改属性,然后用 YArray 的 observeDeep,不能再用 observe 了。
Yjs 的 TypeScript 类型支持不太完善。有些类型太宽泛,比如 YMap 只能定一个类似 Map 的类型,不能传一个特定结构的 interface,要自己用 as 手动强转类型。
另外,一些包的类型也无法使用,虽然我看到这个包下是有类型文件的。不知道是不是 vite 的问题。
Yjs 确实很强大,只要接上 Yjs 的数据结构类型,就能快速实现一个分布式的协同编辑应用。
网站标题:用Yjs+React写一个支持协同的TODO应用
浏览地址:http://www.shufengxianlan.com/qtweb/news4/28204.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联