Tiptap Collaboration 实时协作

Tiptap Collaboration 扩展可以使一个文档同时多个进行实时协作,实时协作基于 Y.js 实现,本文演示的是webrtc实现协作,webrtc 并不会把数据发送到服务器,而是浏览器间直接进行通讯,如果想了解原理请自行学习一下Y.js 和 y-webrtc。也可以查阅详细的说明>>

Install 安装

// 直接运行安装命令可能会出错,请按照错误提示安装对应版本的库
npm install @tiptap/extension-collaboration yjs y-websocket y-prosemirror

Settings 配置

document An initialized Y.js document.

Collaboration.configure({
  document: new Y.Doc(),
})

field Name of a Y.js fragment, can be changed to sync multiple fields with one Y.js document.

Collaboration.configure({
  document: new Y.Doc(),
  field: 'title',
})

fragment A raw Y.js fragment, can be used instead of document and field.

Collaboration.configure({
  fragment: new Y.Doc().getXmlFragment('body'),
})

Commands 命令

undo Undo the last change.

editor.commands.undo()

redo Redo the last change.

editor.commands.redo()

快捷键

CommandWindows/LinuxmacOS
undo()Control ZCmd Z
redoShift Control Z
Control Y
Shift Cmd Z
Cmd Y

源代码

collaboration 源代码

在线例子

在线试一试

Collaboration 例子

  • Vue 例子

  • React 例子

<template>
  <editor-content :editor="editor" />
</template>
<script>
import Collaboration from '@tiptap/extension-collaboration'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Placeholder from '@tiptap/extension-placeholder'
import Text from '@tiptap/extension-text'
import { Editor, EditorContent } from '@tiptap/vue-3'
import { WebrtcProvider } from 'y-webrtc'
import * as Y from 'yjs'

export default {
  components: {
    EditorContent,
  },
  data() {
    return {
      editor: null,
      provider: null,
    }
  },
  mounted() {
    const ydoc = new Y.Doc()
    this.provider = new WebrtcProvider('tiptap-collaboration-extension', ydoc)
    this.editor = new Editor({
      extensions: [
        Document,
        Paragraph,
        Text,
        Collaboration.configure({
          document: ydoc,
        }),
        Placeholder.configure({
          placeholder: 'Write something … It’ll be shared with everyone else looking at this example.',
        }),
      ],
    })
  },
  beforeUnmount() {
    this.editor.destroy()
    this.provider.destroy()
  },
}
</script>
<style>
/* Basic editor styles */
.ProseMirror {
  > * + * {
    margin-top: 0.75em;
  }
}
/* Placeholder (at the top) */
.ProseMirror p.is-editor-empty:first-child::before {
  content: attr(data-placeholder);
  float: left;
  color: #adb5bd;
  pointer-events: none;
  height: 0;
}
</style>
import Collaboration from '@tiptap/extension-collaboration'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Placeholder from '@tiptap/extension-placeholder'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import React from 'react'
import { WebrtcProvider } from 'y-webrtc'
import * as Y from 'yjs'

const ydoc = new Y.Doc()

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const provider = new WebrtcProvider('tiptap-collaboration-extension', ydoc)

export default () => {
  const editor = useEditor({
    extensions: [
      Document,
      Paragraph,
      Text,
      Collaboration.configure({
        document: ydoc,
      }),
      Placeholder.configure({
        placeholder:
          'Write something … It’ll be shared with everyone else looking at this example.',
      }),
    ],
  })
  return <EditorContent editor={editor} />
}

下载教程 Demo

本教程Demo的源码点击这里下载,Tiptap Demo,下载完成后运行npm i初始化依赖包。