探索 Tiptap V3 的最新功能

从 TinyMCE 迁移到 Tiptap

Editor

Tiptap 是强大的 TinyMCE 替代方案。从 TinyMCE 迁移到 Tiptap 非常简单。本文将一步步带你完成迁移流程。

内容迁移

HTML 内容兼容性

TinyMCE 通常以 HTML 格式存储内容,这使得迁移到 Tiptap 变得无缝。Tiptap 可以直接使用 HTML 内容,无需转换:

// 你现有的 TinyMCE 内容
const existingContent = '<p>Hello <strong>world</strong>!</p>'

// 在 Tiptap 中直接使用
const editor = new Editor({
  content: existingContent,
  extensions: [StarterKit],
})

虽然 HTML 完全可用,我们仍推荐将其转换为 Tiptap 的 JSON 格式,以获得更好的性能和易读性。对于批量转换已有内容,可使用 HTML 工具 以编程方式将 HTML 转换为 JSON。

编辑器设置

安装

首先,安装 Tiptap 及相关依赖:

npm install @tiptap/core @tiptap/starter-kit

Tiptap 支持所有现代前端 UI 框架,如 React 和 Vue。请参考我们的安装指南获取框架特定的安装说明。

基本编辑器设置

用 Tiptap 替换原有 TinyMCE 的初始化:

// TinyMCE(之前)
tinymce.init({
  selector: '#editor',
  plugins: 'lists link image table code',
  toolbar: 'undo redo | bold italic | bullist numlist | link image',
})

// Tiptap(之后)
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'

const editor = new Editor({
  element: document.querySelector('#editor'),
  extensions: [StarterKit],
  content: '<p>Hello World!</p>',
})

扩展

了解 Tiptap 的扩展系统

Tiptap 使用模块化的扩展系统,类似于 TinyMCE 的插件结构。每个功能作为独立扩展,可以单独配置。

StarterKit 是所有基础扩展的合集,你可以根据需求添加或移除其他扩展。

请在我们的扩展指南中探索所有可用扩展,或创建自定义扩展支持特殊功能和 HTML 元素。

常见 TinyMCE 插件对应关系

TinyMCE 插件Tiptap 扩展备注
listsBulletListOrderedListListItem包含于 StarterKit
linkLink包含于 StarterKit
imageImage单独提供
tableTable单独提供
codeCodeCodeBlock包含于 StarterKit
textcolorTextStyleColor单独提供
fontsizeTextStyleFontSize单独提供
alignTextAlign单独提供

扩展配置

import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import Image from '@tiptap/extension-image'
import Table from '@tiptap/extension-table'
import TableRow from '@tiptap/extension-table-row'
import TableHeader from '@tiptap/extension-table-header'
import TableCell from '@tiptap/extension-table-cell'

const editor = new Editor({
  extensions: [
    StarterKit,
    // 添加并配置扩展
    Image.configure({
      inline: true,
      allowBase64: true,
    }),
    Table.configure({
      resizable: true,
    }),
    TableRow,
    TableHeader,
    TableCell,
  ],
})

自定义扩展

对于 TinyMCE 自定义插件,你可以创建自定义的 Tiptap 扩展。详细说明请参阅我们的自定义扩展指南

UI 实现

工具栏实现

TinyMCE 的工具栏配置需要转换为 Tiptap 的自定义 UI 组件:

// TinyMCE 工具栏配置
toolbar: 'undo redo | bold italic | bullist numlist'

// Tiptap 对应实现(React 示例)
function Toolbar({ editor }) {
  if (!editor) return null

  return (
    <div className="toolbar">
      <button onClick={() => editor.chain().focus().undo().run()} disabled={!editor.can().undo()}>
        Undo
      </button>
      <button onClick={() => editor.chain().focus().redo().run()} disabled={!editor.can().redo()}>
        Redo
      </button>
      <button
        onClick={() => editor.chain().focus().toggleBold().run()}
        className={editor.isActive('bold') ? 'active' : ''}
      >
        Bold
      </button>
      <button
        onClick={() => editor.chain().focus().toggleItalic().run()}
        className={editor.isActive('italic') ? 'active' : ''}
      >
        Italic
      </button>
    </div>
  )
}

预构建 UI 组件

为加快开发速度,可以使用 Tiptap 预构建的 UI 组件:

菜单系统

TinyMCE 的上下文菜单可以用 Tiptap 的 BubbleMenu 和 FloatingMenu 替代:

import { BubbleMenu } from '@tiptap/react'

function MyEditor() {
  const editor = useEditor({
    extensions: [StarterKit],
  })

  return (
    <>
      <EditorContent editor={editor} />
      <BubbleMenu editor={editor}>
        <button
          onClick={() => editor.chain().focus().toggleBold().run()}
          className={editor.isActive('bold') ? 'active' : ''}
        >
          Bold
        </button>
        <button
          onClick={() => editor.chain().focus().toggleItalic().run()}
          className={editor.isActive('italic') ? 'active' : ''}
        >
          Italic
        </button>
      </BubbleMenu>
    </>
  )
}

迁移检查清单

后续步骤