如何将 Tiptap v2 升级至 v3
Tiptap v3 is a major update with breaking changes. This guide will help you upgrade your Tiptap v2 project to version 3.
Breaking Changes
Package Changes
- UMD builds have been removed (now using tsup)
Some packages may have been removed or renamed, so you may need to update your imports and dependencies. Here are some common changes:
表格相关软件包
- 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'
React 菜单
- 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
迁移示例:
// 迁前
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={{
middleware: [offset(6)],
placement: 'top',
}}
>
{/* 菜单内容 */}
</BubbleMenu>
)- 新的依赖项:
@floating-ui/dom。安装方式:
npm install @floating-ui/dom@^1.6.0Make sure to uninstall tippy.js if you were using it, as it is no longer needed.
npm uninstall tippy.jsAPI Changes Text Style Updates
mergeNestedSpanStyles现在默认为true- 新增文本样式扩展:
font-sizebackground-colorline-height
- 提供
TextStyleKitAPI,用于配置多个文本样式扩展
您可以使用新的 TextStyleKit 简化配置:
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 之前,编辑器会在每次事务导致的状态变化时重新渲染,便于持续跟踪编辑器对象,但可能会影响性能。
此选项默认关闭。启用方法是在配置中添加:
shouldRerenderOnTransaction: true升级后,依赖于编辑器状态的UI元素可能变得无响应。这时可以选择关闭此选项(可能影响性能),或通过手动追踪状态实现同步。例如:
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 提取整个状态或部分值:
const { currentSelection } = useEditorState({
editor,
selector: (snapshot) => {
return { currentSelection: snapshot.editor.state.selection }
},
})这样可以明确提取和管理状态,从而确保UI逻辑的正确性。
命令(Command)变更
clearContent和setContent现在在默认情况下会发出更新setContent的参数签名变为(content, options)insertContent的行为调整为避免在开头拆分文本节点
NodeView 变更
NodeViewRendererProps 中的 getPos 函数现在可以返回 undefined。请确保代码正确处理此情况,例如:
// 之前
const pos = nodeViewProps.getPos()
// 之后
const pos = nodeViewProps.getPos()
if (pos !== undefined) {
// 使用 pos
}已移除功能
editor.getCharacterCount()方法已被移除considerAnyAsEmpty选项已从占位符扩展中移除
新增功能
Extensions 软件包
新推出的 @tiptap/extensions 软件包整合了多项实用扩展:
导入方式将自动升级。
迁移示例:
- import CharacterCount from '@tiptap/extension-character-count'
+ import { CharacterCount } from '@tiptap/extensions'服务器端渲染(SSR)
增强 SSR 支持,可在无需渲染的情况下在服务端运行编辑器:
const editor = new Editor({
element: null, // 选择启用 SSR 模式
content: {
type: 'doc',
content: [
/* 内容省略 */
],
},
extensions: [
/* 扩展列表 */
],
})标记(Mark)视图支持
新增对 mark views 的支持,让您可以自定义标记在编辑器中的呈现方式。例如,用于渲染文本颜色或超链接的自定义UI。
支持 React 和 Vue 3:
// 纯 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 现已默认包含以下扩展:
如果已单独安装这些扩展,可以将它们移除:
- import Link from '@tiptap/extension-link'
- import ListKeymap from '@tiptap/extension-list-keymap'
- import Underline from '@tiptap/extension-underline'如果您正在使用禁用的扩展名,请确保在您的 StarterKit 配置中更新它们的名称:
const editor = new Editor({
extensions: [
StarterKit.configure({
- history: false, // disable history
+ undoRedo: false // disable undo/redo (previously history)
})
]
})迁移步骤
-
更新依赖
- 移除依赖 UMD 的代码
- 安装
@floating-ui/dom(用于气泡和浮动菜单) - 将 Tiptap 包更新到 v3
-
更新菜单实现
- 替换
tippyOptions为 Floating UI 配置 - 更新菜单导入路径,加入
/menus后缀
- 替换
-
审查 NodeView 使用
- 为
getPos添加undefined检查
- 为
-
升级扩展
- 按需迁移到
@tiptap/extensions - 移除冗余的
StarterKit依赖 - 调整文本样式配置
- 按需迁移到
-
审查命令用法
- 更新
setContent调用以适配新签名 - 检查
clearContent在新版本中的行为(默认为发出更新)
- 更新