---
title: "分栏视图"
description: "在两个独立窗格中审阅变更，并与修订记录集成。"
canonical_url: "https://tiptap.zhcndoc.com/compare/guides/split-view"
---

# 分栏视图

在两个独立窗格中审阅变更，并与修订记录集成。

将[修订记录](https://tiptap.zhcndoc.com/tracked-changes/getting-started/overview.md)并排显示：左窗格显示删除内容，右窗格显示新增内容。两个窗格都可以编辑，并会保持对应块对齐。

> **Interactive demo:** [SplitView](https://embed-pro.tiptap.dev/preview/Extensions/SplitView)

## 安装

首先，[联系我们](https://tiptap.dev/contact-sales?form=pilot-program)加入分栏视图试点计划。

> **独立产品:**
>
> [修订记录](https://tiptap.zhcndoc.com/tracked-changes/getting-started/overview.md)和 [Tiptap
> Compare](https://tiptap.zhcndoc.com/compare/getting-started/overview.md) 是与分栏视图不同的产品，需要单独购买。

请先设置[私有注册表](https://tiptap.zhcndoc.com/guides/pro-extensions.md)，然后安装：

```bash
npm install @tiptap-pro/extension-split-view @tiptap-pro/extension-tracked-changes
```

## 连接编辑器

主编辑器是编辑器内容的事实来源。再创建两个编辑器，分别显示分栏视图的左右窗格。将 `TrackedChanges` 扩展添加到三个编辑器，并将 `SplitView` 添加到对应窗格的两个编辑器。

```ts
import { Editor } from '@tiptap/core'
import { TrackedChanges } from '@tiptap-pro/extension-tracked-changes'
import { SplitView, createSplitView } from '@tiptap-pro/extension-split-view'

const mainEditor = new Editor({
  extensions: [
    // ... other extensions
    TrackedChanges,
  ],
    content: '<p>从这里开始写作。</p>',
})

const beforeEditor = new Editor({
  extensions: [
    // ... other extensions
    TrackedChanges,
    SplitView,
  ],
})

const afterEditor = new Editor({
  extensions: [
    // ... other extensions
    TrackedChanges,
    SplitView,
  ],
})

let manager = createSplitView({ mainEditor, beforeEditor, afterEditor })
```

内容由主编辑器管理。`createSplitView()` 将两个窗格连接到主编辑器。编辑以及接受/拒绝操作会在三个编辑器之间同步。

## 排列窗格

打开分栏视图时隐藏主编辑器。为两个窗格设置相同的顶部内边距，并使用共享的滚动容器。

```html
<div id="main" hidden></div>
<div id="split">
  <div id="before"></div>
  <div id="after"></div>
</div>
```

```css
#split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  overflow: auto;
}

#split[hidden] {
  display: none;
}
```

灰色间隔块用于填充高度差或缺失的块。两个间隔块会使用到下一个块的两个间距中较大者作为底部外边距，该间距根据你的 CSS 测量。高度为零的间隔块只增加间距，不显示灰色方框。间隔块永远不会保存到文档中。

## 切换视图

销毁管理器以停止同步并移除窗格过滤；编辑器本身仍然保持存活。

```ts
manager.destroy()
document.querySelector('#split')?.setAttribute('hidden', '')
document.querySelector('#main')?.removeAttribute('hidden')
```

要返回分栏视图，请重新连接。两个窗格会接收主编辑器的当前文档。

```ts
document.querySelector('#main')?.setAttribute('hidden', '')
document.querySelector('#split')?.removeAttribute('hidden')
manager = createSplitView({ mainEditor, beforeEditor, afterEditor })
```

组件卸载时销毁三个编辑器。每个编辑器都有自己的撤销历史；分栏视图不提供共享撤销。

## API 参考

### `SplitView`

将它与 `TrackedChanges` 一起安装在两个窗格中。无需配置；在 `createSplitView()` 连接编辑器之前它保持非活动状态。

### `createSplitView(options): SplitViewManager`

返回一个 `SplitViewManager`。传入三个不同且已挂载、schema 相同的编辑器。一个编辑器只能属于一个活动管理器。

| Option         | Type                                               | Description   |
| -------------- | -------------------------------------------------- | ------------- |
| `mainEditor`   | `Editor`                                           | 提供初始文档。       |
| `beforeEditor` | `Editor`                                           | 显示删除内容和未变化内容。 |
| `afterEditor`  | `Editor`                                           | 显示新增内容和未变化内容。 |
| `createSpacer` | `(options: SplitViewSpacerOptions) => HTMLElement` | 可选的自定义间隔元素。   |

其他类型的建议（例如格式变化）会在两个窗格中继续显示。三个编辑器都保留完整文档，包括在某个窗格中隐藏的内容。再次连接相同编辑器前，请先销毁现有管理器。

### 管理器方法

| Method              | Returns               | Description                   |
| ------------------- | --------------------- | ----------------------------- |
| `getMainEditor()`   | `Editor \| undefined` | 返回主编辑器。                       |
| `getBeforeEditor()` | `Editor \| undefined` | 返回 Before 窗格。                 |
| `getAfterEditor()`  | `Editor \| undefined` | 返回 After 窗格。                  |
| `update()`          | `void`                | 在自定义布局或 CSS 发生变化后安排对齐。        |
| `destroy()`         | `void`                | 停止同步、移除间隔块和过滤并释放资源。可以安全地调用两次。 |

销毁后 getter 会返回 `undefined`。销毁任何已连接的编辑器也会销毁管理器。内容变化、调整大小、图片加载和字体加载都会自动更新对齐。

### 设置间隔块样式

默认间隔块是带有 `tiptap-split-view-spacer` 类的 `div`。可以使用 CSS 设置其背景：

```css
#split {
  --tiptap-split-view-spacer-background: #eee;
}
```

如需自定义元素，请提供 `createSpacer`：

```ts
manager.destroy()
manager = createSplitView({
  mainEditor,
  beforeEditor,
  afterEditor,
  createSpacer({ document }) {
    const spacer = document.createElement('div')
    spacer.style.background = '#eee'
    return spacer
  },
})
```

`SplitViewSpacerOptions` 包含 `document: Document` 和 `side: 'original' | 'modified'`。`createSpacer` 回调应返回 `HTMLElement`；管理器会控制其高度、外边距和可见性。自定义元素不会自动获得默认类名。
