---
title: "如何将 Tiptap v2 升级至 v3"
description: "Upgrade your Tiptap v2 project to version 3. Learn about the changes and how to migrate your project."
canonical_url: "https://tiptap.zhcndoc.com/guides/upgrade-tiptap-v2"
---

# 如何将 Tiptap v2 升级至 v3

Upgrade your Tiptap v2 project to version 3. Learn about the changes and how to migrate your project.

Tiptap v3 是一次包含重大更改的主要更新。本指南将帮助你将 Tiptap v2 项目升级到版本 3。

## 重大更改

### 包更改

- 已移除 UMD 构建（现在使用 tsup）

某些包可能已被移除或重命名，因此你可能需要更新你的导入和依赖。以下是一些常见的更改：

```diff
表格相关软件包
- import Table from '@tiptap/extension-table'
- import TableRow from '@tiptap/extension-table-row'
- import TableCell from '@tiptap/extension-table-cell'
- import TableHeader from '@tiptap/extension-table-header'
+ import { Table, TableRow, TableCell, TableHeader } from '@tiptap/extension-table'

列表相关软件包
- import BulletList from '@tiptap/extension-bullet-list'
- import OrderedList from '@tiptap/extension-ordered-list'
- import ListItem from '@tiptap/extension-list-item'
- import ListKeymap from '@tiptap/extension-list-keymap'
- import TaskList from '@tiptap/extension-task-list'
- import TaskItem from '@tiptap/extension-task-item'
+ import { BulletList, OrderedList, ListItem, ListKeymap, TaskList, TaskItem } from '@tiptap/extension-list'

扩展
- import Focus from '@tiptap/extension-focus'
- import Placeholder from '@tiptap/extension-placeholder'
- import History from '@tiptap/extension-history'
- import Dropcursor from '@tiptap/extension-dropcursor'
- import Gapcursor from '@tiptap/extension-gapcursor'
- import CharacterCount from '@tiptap/extension-character-count'
+ import { Focus, Placeholder, UndoRedo, Dropcursor, Gapcursor, CharacterCount } from '@tiptap/extensions'

CollaborationCursor
- import CollaborationCursor from '@tiptap/extension-collaboration-cursor'
+ import CollaborationCaret from '@tiptap/extension-collaboration-caret'

Collaboration History
- import CollaborationHistory from '@tiptap-pro/extension-collaboration-history'
+ import Snapshot from '@tiptap-pro/extension-snapshot'

React Menus
- import { BubbleMenu, FloatingMenu } from '@tiptap/react'
+ import { BubbleMenu, FloatingMenu } from '@tiptap/react/menus'

Vue 3 菜单
- import { BubbleMenu, FloatingMenu } from '@tiptap/vue-3'
+ import { BubbleMenu, FloatingMenu } from '@tiptap/vue-3/menus'

Vue 2 菜单
- import { BubbleMenu, FloatingMenu } from '@tiptap/vue-2'
+ import { BubbleMenu, FloatingMenu } from '@tiptap/vue-2/menus'
```

### 菜单系统

所有悬浮元素的库由 Tippy.js 替换为 Floating UI。这影响以下包：

- @tiptap/extension-bubble-menu
- @tiptap/extension-drag-handle
- @tiptap/extension-drag-handle-react
- @tiptap/extension-drag-handle-vue-2
- @tiptap/extension-drag-handle-vue-3
- @tiptap/extension-floating-menu
- @tiptap/extension-mention
- @tiptap/suggestion
- @tiptap-pro/extension-emoji

迁移示例：

```tsx
// 迁前
import { BubbleMenu } from '@tiptap/react'

const 菜单 = <BubbleMenu tippyOptions={{ duration: 100 }}>{/* 菜单内容 */}</BubbleMenu>

// 迁后
import { BubbleMenu } from '@tiptap/react/menus'
import { offset } from '@floating-ui/dom'
const 菜单 = (
  <BubbleMenu
    options={{
      offset: 6,
      placement: 'top',
    }}
  >
    {/* 菜单内容 */}
  </BubbleMenu>
)
```

- 新的依赖项：`@floating-ui/dom`。安装方式：

```bash
npm install @floating-ui/dom@^1.6.0
```

Make sure to uninstall `tippy.js` if you were using it, as it is no longer needed.

```bash
npm uninstall tippy.js
```

### API Changes Text Style Updates

- `mergeNestedSpanStyles` 现在默认为 `true`
- 新增文本样式扩展：
  - `font-size`
  - `background-color`
  - `line-height`
- 提供 `TextStyleKit` API，用于配置多个文本样式扩展

您可以使用新的 `TextStyleKit` 简化配置：

```ts
import { TextStyleKit } from '@tiptap/extension-text-style'

new Editor({
  extensions: [
    TextStyleKit.configure({
      backgroundColor: {
        types: ['textStyle'],
      },
      color: {
        types: ['textStyle'],
      },
      fontFamily: {
        types: ['textStyle'],
      },
      fontSize: {
        types: ['textStyle'],
      },
      lineHeight: {
        types: ['textStyle'],
      },
    }),
  ],
})
```

### 引入 `shouldRerenderOnTransaction`

`@tiptap/react` 中的 Editor 配置现在支持 `shouldRerenderOnTransaction`，用于控制组件是否重渲染。

在 3.0.0 之前，编辑器会在每次事务导致的状态变化时重新渲染，便于持续跟踪编辑器对象，但可能会影响性能。

此选项默认关闭。启用方法是在配置中添加：

```js
shouldRerenderOnTransaction: true
```

升级后，依赖于编辑器状态的UI元素可能变得无响应。这时可以选择关闭此选项（可能影响性能），或通过手动追踪状态实现同步。例如：

```js
function MyEditor() {
  const [selection, setSelection] = useState({ from: 0, to: 0 });

  const editor = useEditor({
    // 其他配置项
    onTransaction({ transaction }) {
      setSelection({
        from: transaction.selection.from,
        to: transaction.selection.to,
      });
    },
  });
}
```

也可以使用 `useEditorState` 提取整个状态或部分值：

```ts
const { currentSelection } = useEditorState({
  editor,
  selector: (snapshot) => {
    return { currentSelection: snapshot.editor.state.selection }
  },
})
```

这样可以明确提取和管理状态，从而确保UI逻辑的正确性。

### 命令（Command）变更

- `clearContent` 和 `setContent` 现在在默认情况下会发出更新
- `setContent` 的参数签名变为 `(content, options)`
- `insertContent` 的行为调整为避免在开头拆分文本节点

### NodeView 变更

`NodeViewRendererProps` 中的 `getPos` 函数现在可以返回 `undefined`。请确保代码正确处理此情况，例如：

```ts
// 之前
const pos = nodeViewProps.getPos()

// 之后
const pos = nodeViewProps.getPos()
if (pos !== undefined) {
  // 使用 pos
}
```

### 已移除功能

- `editor.getCharacterCount()` 方法已被移除
- `considerAnyAsEmpty` 选项已从占位符扩展中移除

## 新增功能

### Extensions 软件包

新推出的 `@tiptap/extensions` 软件包整合了多项实用扩展：

- [CharacterCount](https://tiptap.zhcndoc.com/editor/extensions/functionality/character-count.md)
- [Dropcursor](https://tiptap.zhcndoc.com/editor/extensions/functionality/dropcursor.md)
- [Gapcursor](https://tiptap.zhcndoc.com/editor/extensions/functionality/gapcursor.md)
- [History](https://tiptap.zhcndoc.com/editor/extensions/functionality/undo-redo.md) (now named `UndoRedo`)
- [Placeholder](https://tiptap.zhcndoc.com/editor/extensions/functionality/placeholder.md)
- [TrailingNode](https://tiptap.zhcndoc.com/editor/extensions/functionality/trailing-node.md)
- [Focus](https://tiptap.zhcndoc.com/editor/extensions/functionality/focus.md)
- [Selection](https://tiptap.zhcndoc.com/editor/extensions/functionality/selection.md)

导入方式将自动升级。

迁移示例：

```diff
- import CharacterCount from '@tiptap/extension-character-count'
+ import { CharacterCount } from '@tiptap/extensions'
```

### 服务器端渲染（SSR）

增强 SSR 支持，可在无需渲染的情况下在服务端运行编辑器：

```ts
const editor = new Editor({
  element: null, // 选择启用 SSR 模式
  content: {
    type: 'doc',
    content: [
      /* 内容省略 */
    ],
  },
  extensions: [
    /* 扩展列表 */
  ],
})
```

### 标记（Mark）视图支持

新增对 [mark views](https://prosemirror.net/docs/ref/#view.MarkView) 的支持，让您可以自定义标记在编辑器中的呈现方式。例如，用于渲染文本颜色或超链接的自定义UI。

支持 React 和 Vue 3：

```ts
// 纯 JavaScript
import { Mark } from '@tiptap/core'

Mark.create({
  // 其他选项...
  addMarkView() {
    return ({ mark, HTMLAttributes }) => {
      const dom = document.createElement('b')
      const contentDOM = document.createElement('span')

      dom.appendChild(contentDOM)

      return {
        dom,
        contentDOM,
      }
    }
  },
})

// React
import { Mark } from '@tiptap/core'
import { ReactMarkViewRenderer } from '@tiptap/react'

Mark.create({
  // 其他配置
  addMarkView() {
    return ReactMarkViewRenderer(YourComponent)
  },
})

// Vue 3
import { Mark } from '@tiptap/core'
import { VueMarkViewRenderer } from '@tiptap/vue-3'

Mark.create({
  addMarkView() {
    return VueMarkViewRenderer(VueComponent)
  },
})
```

### 其他改进

- 新增删除事件追踪
- HTML 解析提升，采用 `happy-dom-without-node`
- 增强对节点和标记属性的验证
- 提升事务处理性能

## StarterKit 更新

StarterKit 现已默认包含以下扩展：

- [Link](https://tiptap.zhcndoc.com/editor/extensions/marks/link.md)
- [ListKeymap](https://tiptap.zhcndoc.com/editor/extensions/functionality/listkeymap.md)
- [Underline](https://tiptap.zhcndoc.com/editor/extensions/marks/underline.md)

如果已单独安装这些扩展，可以将它们移除：

```diff
- import Link from '@tiptap/extension-link'
- import ListKeymap from '@tiptap/extension-list-keymap'
- import Underline from '@tiptap/extension-underline'
```

如果您正在使用禁用的扩展名，请确保在您的 StarterKit 配置中更新它们的名称：

```diff
const editor = new Editor({
  extensions: [
    StarterKit.configure({
-      history: false, // disable history
+      undoRedo: false // disable undo/redo (previously history)
    })
  ]
})
```

## 迁移步骤

1. 更新依赖

   - 移除依赖 UMD 的代码
   - 安装 `@floating-ui/dom`（用于气泡和浮动菜单）
   - 将 Tiptap 包更新到 v3

2. 更新菜单实现

   - 替换 `tippyOptions` 为 Floating UI 配置
   - 更新菜单导入路径，加入 `/menus` 后缀

3. 审查 NodeView 使用

   - 为 `getPos` 添加 `undefined` 检查

4. 升级扩展

   - 按需迁移到 `@tiptap/extensions`
   - 移除冗余的 `StarterKit` 依赖
   - 调整文本样式配置

5. 审查命令用法

   - 更新 `setContent` 调用以适配新签名
   - 检查 `clearContent` 在新版本中的行为（默认为发出更新）
