协同编辑
@univerjs/preset-docs-collaboration
注意事项
协同编辑功能需要 Univer 服务端支持,请确保你已经正确安装并配置了 Univer 服务端。具体请参考:升级 Pro
协同编辑功能允许多个用户同时编辑同一文档,实时同步更改,适用于团队协作和多人编辑场景。
预设模式
安装
@univerjs/preset-docs-collaboration 的 UniverDocsCollaborationPreset
预设在运行时依赖 UniverDocsDrawingPreset
和 UniverDocsAdvancedPreset
预设,请先安装 @univerjs/preset-docs-drawing 和 @univerjs/preset-docs-advanced。
npm install @univerjs/preset-docs-drawing @univerjs/preset-docs-advanced @univerjs/preset-docs-collaboration
使用
import { UniverDocsAdvancedPreset } from '@univerjs/preset-docs-advanced'
import UniverPresetDocsAdvancedZhCN from '@univerjs/preset-docs-advanced/locales/zh-CN'
import { UniverDocsCollaborationPreset } from '@univerjs/preset-docs-collaboration'
import UniverPresetDocsCollaborationZhCN from '@univerjs/preset-docs-collaboration/locales/zh-CN'
import { UniverDocsCorePreset } from '@univerjs/preset-docs-core'
import UniverPresetDocsCoreZhCN from '@univerjs/preset-docs-core/locales/zh-CN'
import { UniverDocsDrawingPreset } from '@univerjs/preset-docs-drawing'
import UniverPresetDocsDrawingZhCN from '@univerjs/preset-docs-drawing/locales/zh-CN'
import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'
import '@univerjs/presets/lib/styles/preset-docs-core.css'
import '@univerjs/preset-docs-drawing/lib/index.css'
import '@univerjs/preset-docs-advanced/lib/index.css'
import '@univerjs/preset-docs-collaboration/lib/index.css'
const { univerAPI } = createUniver({
locale: LocaleType.ZH_CN,
locales: {
[LocaleType.ZH_CN]: mergeLocales(
UniverPresetDocsCoreZhCN,
UniverPresetDocsDrawingZhCN,
UniverPresetDocsAdvancedZhCN,
UniverPresetDocsCollaborationZhCN,
),
},
collaboration: true,
presets: [
UniverDocsCorePreset(),
UniverDocsDrawingPreset({
collaboration: true,
}),
UniverDocsAdvancedPreset({
collaboration: true,
}),
UniverDocsCollaborationPreset({
universerEndpoint: 'http://localhost:3010',
}),
],
})
如果你拥有 Univer 的商业许可证,请参考在客户端使用许可证进行配置。
插件模式
安装
npm install @univerjs-pro/collaboration @univerjs-pro/collaboration-client @univerjs-pro/collaboration-client-ui
使用
import { UniverCollaborationPlugin } from '@univerjs-pro/collaboration'
import { UniverCollaborationClientPlugin } from '@univerjs-pro/collaboration-client'
import { BrowserCollaborationSocketService, UniverCollaborationClientUIPlugin } from '@univerjs-pro/collaboration-client-ui'
import CollaborationClientZhCN from '@univerjs-pro/collaboration-client/locale/zh-CN'
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'
import '@univerjs-pro/collaboration-client/facade'
import '@univerjs-pro/collaboration-client-ui/facade'
import '@univerjs-pro/collaboration-client/lib/index.css'
const univer = new Univer({
locale: LocaleType.ZH_CN,
locales: {
[LocaleType.ZH_CN]: mergeLocales(
CollaborationClientZhCN,
),
},
})
// 通过将 override 选项设置为 [[IAuthzIoService, null]],可以告诉 Univer 不要注册内置的 IAuthzIoService。
// 通过将 override 选项设置为 [[IUndoRedoService, null]],可以告诉 Univer 不要注册内置的 IUndoRedoService
// 这样,Univer 将使用 UniverCollaborationPlugin 中提供的服务作为权限、重做恢复服务的实现。
const univer = new Univer({
override: [
[IAuthzIoService, null],
[IUndoRedoService, null],
],
})
univer.registerPlugin(UniverCollaborationPlugin)
univer.registerPlugin(UniverCollaborationClientPlugin, {
socketService: BrowserCollaborationSocketService,
authzUrl: 'http://localhost:3010/universer-api/authz',
snapshotServerUrl: 'http://localhost:3010/universer-api/snapshot',
collabSubmitChangesetUrl: 'http://localhost:3010/universer-api/comb',
collabWebSocketUrl: 'ws://localhost:3010/universer-api/comb/connect',
})
univer.registerPlugin(UniverCollaborationClientUIPlugin)
如果你拥有 Univer 的商业许可证,请参考在客户端使用许可证进行配置。
协同文档数据
协同编辑插件依赖 Univer 服务,协同文档的数据存储在 Univer 服务中。
unitId
每篇协同文档在 Univer 服务中都有一个唯一的 unitId
。Univer 协同客户端使用 unitId
可从 Univer 服务获取到对应的协同文档数据进行协同编辑。
type
type
是协同文档的类型,协同文档的类型决定了协同文档的初始数据结构。
创建协同文档
有多种方式在 Univer 服务中创建协同文档:
通过 URL 参数加载协同文档
@univerjs-pro/collaboration-client 插件内部提供了根据 URL 参数 unit
和 type
自动加载对应的数据的功能,这可以简化一些场景下的数据加载逻辑。
如果你想使用该特性,你需要适当地修改一下原有的加载数据逻辑,并将 unit
和 type
参数添加到 URL 中,如下所示:
import { UniverInstanceType } from '@univerjs/core'
// 预设模式下 `UniverInstanceType` 可从 @univerjs/presets 导入
import { UniverInstanceType } from '@univerjs/presets'
// 原有逻辑,只适用于非协同文档
univer.createUnit(UniverInstanceType.UNIVER_DOC, {})
// 修改后的逻辑,适用于协同文档
const url = new URL(window.location.href)
const unit = url.searchParams.get('unit')
if (unit) {
// 如果 URL 中包含 unit 参数,则自动加载数据
} else {
// 创建一个新的文档
fetch(`/universer-api/snapshot/${UniverInstanceType.UNIVER_DOC}/unit/-/create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: UniverInstanceType.UNIVER_DOC, // instance type
name: 'New Doc By Univer', // doc name
creator: 'user', // creator name
}),
}).then((response) => {
if (!response.ok) {
throw new Error('create unit failed')
}
return response.json()
}).then((data) => {
if (!data.unitID) {
throw new Error('create unit failed')
}
url.searchParams.set('unit', data.unitID)
url.searchParams.set('type', String(UniverInstanceType.UNIVER_DOC))
window.location.href = url.toString()
}).catch((error) => {
console.error(error)
})
}
Facade API
加载协同文档
如果你不想使用 URL 参数来加载协同文档,你也可以通过 Facade API 来加载协同文档。
const collaboration = univerAPI.getCollaboration()
const workbook = await collaboration.loadSheetAsync('your-unit-id')
拓展阅读
如果你想进一步了解协同编辑的工作原理,可以阅读以下文章:
你觉得这篇文档如何?