TipTap简介

第 1 章:Tiptap 简介

本章概述

欢迎来到 Tiptap 的世界!在本章中,我们将全面了解 Tiptap 是什么、它的核心特性、以及为什么它是构建现代富文本编辑器的最佳选择之一。

学习目标:

  • 理解 Tiptap 的定位和设计理念
  • 了解 Tiptap 的核心特性和优势
  • 对比 Tiptap 与其他编辑器的区别
  • 明确 Tiptap 的适用场景
  • 了解 Tiptap 的生态系统

前置知识:

  • 基础的 Web 开发知识(HTML、CSS、JavaScript)
  • 了解现代前端框架(React、Vue 等)会有帮助,但不是必需的

预计学习时间: 20-30 分钟


1. 什么是 Tiptap

1.1 定义

Tiptap 是一个基于 ProseMirror无头(Headless)框架无关的富文本编辑器框架。

让我们拆解这个定义:

🎯 无头(Headless)

Tiptap 不提供预设的 UI 界面,你需要自己设计和实现编辑器的外观。

ini 复制代码
传统编辑器(如 TinyMCE):
┌─────────────────────────────┐
│  [B] [I] [U] [链接] [图片]  │ ← 预设的工具栏
├─────────────────────────────┤
│                             │
│  编辑区域                    │
│                             │
└─────────────────────────────┘

Tiptap(无头):
┌─────────────────────────────┐
│                             │
│  编辑区域(只有这个)         │
│                             │
└─────────────────────────────┘
     ↓
你可以自由设计任何 UI

优势:

  • ✅ 完全自定义 UI 和交互
  • ✅ 与你的设计系统完美融合
  • ✅ 更小的包体积(不包含 UI 代码)
  • ✅ 更灵活的用户体验

劣势:

  • ❌ 需要自己实现 UI(工具栏、菜单等)
  • ❌ 初期开发成本较高
🔧 框架无关(Framework Agnostic)

Tiptap 可以在任何前端框架中使用,也可以在原生 JavaScript 中使用。

支持的框架:

  • ✅ React
  • ✅ Vue 2 / Vue 3
  • ✅ Angular
  • ✅ Svelte
  • ✅ Alpine.js
  • ✅ Vanilla JavaScript

示例:

tsx 复制代码
// React
import { useEditor, EditorContent } from '@tiptap/react'

// Vue 3
import { useEditor, EditorContent } from '@tiptap/vue-3'

// Vanilla JS
import { Editor } from '@tiptap/core'
🏗️ 基于 ProseMirror

Tiptap 是对 ProseMirror 的高级封装,提供了更友好的 API。

markdown 复制代码
ProseMirror(底层)
    ↓
Tiptap(高级封装)
    ↓
你的应用

ProseMirror 的优势:

  • 强大的文档模型(Schema)
  • 高性能的渲染引擎
  • 成熟的协同编辑支持
  • 灵活的插件系统

Tiptap 的改进:

  • 更简单的 API
  • 更好的 TypeScript 支持
  • 开箱即用的扩展
  • 现代化的开发体验

1.2 核心理念

Tiptap 的设计遵循以下核心理念:

1. 可扩展性(Extensibility)

一切都是扩展(Extension)。

typescript 复制代码
// 编辑器由扩展组成
const editor = new Editor({
  extensions: [
    Document,      // 文档扩展
    Paragraph,     // 段落扩展
    Text,          // 文本扩展
    Bold,          // 加粗扩展
    Italic,        // 斜体扩展
    // ... 更多扩展
  ],
})

好处:

  • 按需加载,减小包体积
  • 易于添加自定义功能
  • 社区扩展丰富
2. 类型安全(Type Safety)

完整的 TypeScript 支持。

typescript 复制代码
// 类型推断和检查
editor.chain()
  .focus()
  .toggleBold()  // ✅ 类型安全
  .toggleFoo()   // ❌ 编译错误:方法不存在
  .run()
3. 声明式 API(Declarative API)

使用链式调用执行命令。

typescript 复制代码
// 声明式:描述"做什么"
editor.chain()
  .focus()
  .setHeading({ level: 1 })
  .insertContent('Hello World')
  .run()

// vs 命令式:描述"怎么做"
editor.focus()
const tr = editor.state.tr
tr.setNodeMarkup(0, schema.nodes.heading, { level: 1 })
// ... 更多底层操作
4. 协同优先(Collaboration First)

内置对协同编辑的支持。

typescript 复制代码
import Collaboration from '@tiptap/extension-collaboration'
import * as Y from 'yjs'

const ydoc = new Y.Doc()

const editor = new Editor({
  extensions: [
    StarterKit,
    Collaboration.configure({
      document: ydoc,
    }),
  ],
})

2. 为什么选择 Tiptap

2.1 核心优势

✨ 1. 现代化的开发体验

特点:

  • 完整的 TypeScript 支持
  • 优秀的文档和示例
  • 活跃的社区和生态
  • 持续的更新和维护

示例:

typescript 复制代码
// 类型提示和自动补全
editor.chain()
  .focus()
  .toggle // ← IDE 会提示所有 toggle 开头的方法
  .run()
🎨 2. 完全自定义的 UI

特点:

  • 无预设 UI,完全由你控制
  • 与任何 UI 库/框架集成
  • 支持任何设计系统

示例:

tsx 复制代码
// 使用 Material-UI
<Toolbar>
  <IconButton onClick={() => editor.chain().focus().toggleBold().run()}>
    <FormatBoldIcon />
  </IconButton>
</Toolbar>

// 使用 Ant Design
<Space>
  <Button onClick={() => editor.chain().focus().toggleBold().run()}>
    <BoldOutlined />
  </Button>
</Space>

// 使用 Tailwind CSS
<button
  onClick={() => editor.chain().focus().toggleBold().run()}
  className="px-4 py-2 bg-blue-500 text-white rounded"
>
  Bold
</button>
🔌 3. 丰富的扩展生态

官方扩展:

  • 100+ 个官方扩展
  • 覆盖常见的编辑器功能
  • 持续更新和维护

社区扩展:

  • 数百个社区扩展
  • 涵盖各种特殊需求
  • 开源且可自定义

扩展分类:

类型 示例 数量
Nodes(节点) Paragraph, Heading, Image, Table 20+
Marks(标记) Bold, Italic, Link, Highlight 10+
Extensions(功能) History, Collaboration, Placeholder 70+
🤝 4. 强大的协同编辑

特点:

  • 基于 Y.js(CRDT)
  • 支持实时协同
  • 离线编辑和冲突解决
  • 协作光标和用户状态

应用场景:

  • 团队文档协作(类似 Google Docs)
  • 实时笔记应用
  • 协同编辑平台
⚡ 5. 高性能

优化:

  • 虚拟 DOM 渲染
  • 增量更新
  • 懒加载扩展
  • 优化的文档结构

性能对比:

makefile 复制代码
文档大小: 10,000 字
操作: 插入 1,000 个字符

Tiptap:     ~50ms
Draft.js:   ~200ms
Slate:      ~150ms

💡 注意: 性能数据仅供参考,实际性能取决于具体使用场景。

🛡️ 6. 类型安全

TypeScript 支持:

  • 完整的类型定义
  • 类型推断
  • 编译时错误检查

示例:

typescript 复制代码
// ✅ 类型安全
editor.chain()
  .focus()
  .setHeading({ level: 1 })  // level 必须是 1-6
  .run()

// ❌ 编译错误
editor.chain()
  .focus()
  .setHeading({ level: 7 })  // 错误:level 超出范围
  .run()

2.2 与其他编辑器的对比

对比表格
特性 Tiptap Draft.js Slate Quill TinyMCE
框架支持 React, Vue, Angular, Svelte 仅 React 仅 React 框架无关 框架无关
无头设计
TypeScript ✅ 完整 ⚠️ 部分 ✅ 完整 ⚠️ 部分 ⚠️ 部分
协同编辑 ✅ 内置 ❌ 需自行实现 ⚠️ 需插件 ❌ 需自行实现 ✅ 付费
扩展系统 ✅ 强大 ⚠️ 一般 ✅ 强大 ⚠️ 一般 ✅ 强大
学习曲线 ⚠️ 中等 ⚠️ 陡峭 ⚠️ 陡峭 ✅ 平缓 ✅ 平缓
包体积 ⚠️ 中等 (45KB) ⚠️ 大 (100KB+) ⚠️ 中等 (50KB) ✅ 小 (43KB) ❌ 很大 (500KB+)
性能 ✅ 优秀 ⚠️ 一般 ✅ 优秀 ✅ 优秀 ⚠️ 一般
社区活跃度 ✅ 非常活跃 ⚠️ 维护模式 ✅ 活跃 ⚠️ 一般 ✅ 活跃
商业支持 ✅ 有 ❌ 无 ❌ 无 ❌ 无 ✅ 有
开源协议 MIT MIT MIT BSD GPL/商业
详细对比

1. Tiptap vs Draft.js

typescript 复制代码
// Draft.js(仅 React,API 复杂)
const [editorState, setEditorState] = useState(
  EditorState.createEmpty()
)

const handleBold = () => {
  setEditorState(
    RichUtils.toggleInlineStyle(editorState, 'BOLD')
  )
}

// Tiptap(多框架,API 简洁)
const editor = useEditor({
  extensions: [StarterKit],
})

const handleBold = () => {
  editor.chain().focus().toggleBold().run()
}

优势:

  • ✅ 更简洁的 API
  • ✅ 支持多框架
  • ✅ 内置协同编辑
  • ✅ 更好的 TypeScript 支持

2. Tiptap vs Slate

typescript 复制代码
// Slate(需要更多样板代码)
const [editor] = useState(() => withReact(createEditor()))

const handleBold = () => {
  const isActive = isMarkActive(editor, 'bold')
  if (isActive) {
    Editor.removeMark(editor, 'bold')
  } else {
    Editor.addMark(editor, 'bold', true)
  }
}

// Tiptap(更高级的抽象)
const editor = useEditor({
  extensions: [StarterKit],
})

const handleBold = () => {
  editor.chain().focus().toggleBold().run()
}

优势:

  • ✅ 更高级的抽象
  • ✅ 开箱即用的扩展
  • ✅ 更好的文档
  • ✅ 内置协同编辑

3. Tiptap vs Quill

javascript 复制代码
// Quill(有预设 UI)
const quill = new Quill('#editor', {
  theme: 'snow',  // 必须使用预设主题
  modules: {
    toolbar: [['bold', 'italic']]  // 预设工具栏
  }
})

// Tiptap(无头设计)
const editor = new Editor({
  element: document.querySelector('#editor'),
  extensions: [StarterKit],
})

// 自定义工具栏(完全自由)
<button onClick={() => editor.chain().focus().toggleBold().run()}>
  Bold
</button>

优势:

  • ✅ 完全自定义 UI
  • ✅ 更强大的扩展系统
  • ✅ 更好的 TypeScript 支持
  • ✅ 内置协同编辑

4. Tiptap vs TinyMCE

javascript 复制代码
// TinyMCE(传统编辑器,包体积大)
tinymce.init({
  selector: '#editor',
  plugins: 'lists link image',  // 需要配置插件
  toolbar: 'bold italic | bullist numlist',
  // 500KB+ 的包体积
})

// Tiptap(现代编辑器,按需加载)
const editor = new Editor({
  element: document.querySelector('#editor'),
  extensions: [
    StarterKit,  // 只加载需要的扩展
  ],
  // ~45KB 的核心包
})

优势:

  • ✅ 更小的包体积
  • ✅ 按需加载
  • ✅ 现代化的 API
  • ✅ 开源且免费

2.3 选择 Tiptap 的场景

✅ 适合使用 Tiptap 的场景

1. 需要自定义 UI 的项目

  • 有自己的设计系统
  • 需要与现有 UI 库集成
  • 需要独特的用户体验

2. 协同编辑应用

  • 团队文档协作
  • 实时笔记应用
  • 多人编辑平台

3. 现代前端项目

  • 使用 React、Vue、Angular 等框架
  • 需要 TypeScript 支持
  • 追求高性能

4. 需要高度定制的编辑器

  • 特殊的内容类型(如代码、数学公式)
  • 自定义的编辑行为
  • 复杂的业务逻辑

5. 长期维护的项目

  • 需要稳定的技术栈
  • 需要活跃的社区支持
  • 需要持续的更新
❌ 不适合使用 Tiptap 的场景

1. 快速原型开发

  • 需要立即可用的编辑器
  • 没有时间自定义 UI
  • 推荐:Quill、TinyMCE

2. 简单的文本编辑需求

  • 只需要基础的格式化
  • 不需要复杂功能
  • 推荐:<textarea> + Markdown

3. 不熟悉现代前端技术

  • 不了解 React、Vue 等框架
  • 不熟悉 npm/webpack
  • 推荐:传统的 WYSIWYG 编辑器

4. 需要开箱即用的 UI

  • 没有设计资源
  • 需要预设的工具栏和菜单
  • 推荐:TinyMCE、CKEditor

3. Tiptap 的核心特性

3.1 扩展系统

Tiptap 的一切都是扩展。

扩展类型

1. Nodes(节点)

块级内容,如段落、标题、图片。

typescript 复制代码
import { Node } from '@tiptap/core'

const Paragraph = Node.create({
  name: 'paragraph',
  group: 'block',
  content: 'inline*',
  // ...
})

2. Marks(标记)

内联样式,如加粗、斜体、链接。

typescript 复制代码
import { Mark } from '@tiptap/core'

const Bold = Mark.create({
  name: 'bold',
  parseHTML: () => [{ tag: 'strong' }],
  renderHTML: () => ['strong', 0],
  // ...
})

3. Extensions(功能扩展)

功能性扩展,如历史记录、占位符。

typescript 复制代码
import { Extension } from '@tiptap/core'

const History = Extension.create({
  name: 'history',
  addCommands() {
    return {
      undo: () => ({ commands }) => commands.undo(),
      redo: () => ({ commands }) => commands.redo(),
    }
  },
  // ...
})
StarterKit

官方提供的扩展集合,包含最常用的 15+ 个扩展。

typescript 复制代码
import StarterKit from '@tiptap/starter-kit'

const editor = new Editor({
  extensions: [
    StarterKit,  // 一次性加载所有基础扩展
  ],
})

// StarterKit 包含:
// - Document, Paragraph, Text
// - Heading, Blockquote, CodeBlock
// - BulletList, OrderedList, ListItem
// - Bold, Italic, Strike, Code
// - HardBreak, HorizontalRule
// - History, Dropcursor, Gapcursor

3.2 Commands(命令系统)

Commands 是执行编辑器操作的方式。

基本用法
typescript 复制代码
// 单个命令
editor.commands.toggleBold()

// 链式调用
editor.chain()
  .focus()
  .toggleBold()
  .toggleItalic()
  .run()

// 检查命令是否可用
if (editor.can().toggleBold()) {
  editor.chain().focus().toggleBold().run()
}
常用命令
typescript 复制代码
// 文本格式
editor.chain().focus().toggleBold().run()
editor.chain().focus().toggleItalic().run()
editor.chain().focus().toggleStrike().run()

// 标题
editor.chain().focus().setHeading({ level: 1 }).run()
editor.chain().focus().toggleHeading({ level: 2 }).run()

// 列表
editor.chain().focus().toggleBulletList().run()
editor.chain().focus().toggleOrderedList().run()

// 内容操作
editor.chain().focus().insertContent('Hello').run()
editor.chain().focus().setContent('<p>Hello</p>').run()
editor.commands.clearContent()

// 历史记录
editor.chain().focus().undo().run()
editor.chain().focus().redo().run()

3.3 Schema(文档模式)

Schema 定义了文档的结构和规则。

文档结构
scss 复制代码
Document(文档)
├── Heading(标题)
│   └── Text(文本)
├── Paragraph(段落)
│   ├── Text(文本)
│   ├── Bold(加粗标记)
│   └── Link(链接标记)
└── Image(图片)
内容表达式
typescript 复制代码
// Paragraph 可以包含任意内联内容
content: 'inline*'

// Heading 可以包含文本和标记
content: 'text*'

// Document 必须包含至少一个块级元素
content: 'block+'

3.4 协同编辑

基于 Y.js(CRDT)的实时协同编辑。

基本配置
typescript 复制代码
import Collaboration from '@tiptap/extension-collaboration'
import CollaborationCursor from '@tiptap/extension-collaboration-cursor'
import * as Y from 'yjs'
import { WebsocketProvider } from 'y-websocket'

// 创建 Y.js 文档
const ydoc = new Y.Doc()

// 连接到协同服务器
const provider = new WebsocketProvider(
  'ws://localhost:1234',
  'document-name',
  ydoc
)

// 配置编辑器
const editor = new Editor({
  extensions: [
    StarterKit.configure({
      history: false,  // 禁用本地历史记录
    }),
    Collaboration.configure({
      document: ydoc,
    }),
    CollaborationCursor.configure({
      provider,
      user: {
        name: 'John Doe',
        color: '#f783ac',
      },
    }),
  ],
})
特性
  • ✅ 实时同步
  • ✅ 离线编辑
  • ✅ 冲突自动解决
  • ✅ 协作光标
  • ✅ 用户状态

4. Tiptap 生态系统

4.1 官方包

less 复制代码
@tiptap/core          - 核心包
@tiptap/react         - React 集成
@tiptap/vue-2         - Vue 2 集成
@tiptap/vue-3         - Vue 3 集成
@tiptap/starter-kit   - 基础扩展集合
@tiptap/extension-*   - 100+ 官方扩展
@tiptap/pm            - ProseMirror 依赖

4.2 Pro 扩展(付费)

Tiptap 提供了一些高级的付费扩展:

  • Emoji - 表情符号支持
  • FileHandler - 文件拖放处理
  • Mathematics - LaTeX 数学公式
  • UniqueID - 节点唯一 ID
  • TableOfContents - 目录生成
  • Comments - 评论系统

定价:

  • 个人开发者:$99/年
  • 团队:$299/年
  • 企业:联系销售

4.3 社区资源


5. 快速开始预览

让我们快速预览一下 Tiptap 的使用:

tsx 复制代码
// 1. 安装
npm install @tiptap/react @tiptap/starter-kit

// 2. 创建编辑器
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'

function Editor() {
  const editor = useEditor({
    extensions: [StarterKit],
    content: '<p>Hello World! 🌍</p>',
  })

  return <EditorContent editor={editor} />
}

// 3. 添加工具栏
function Toolbar({ editor }) {
  return (
    <div>
      <button onClick={() => editor.chain().focus().toggleBold().run()}>
        Bold
      </button>
      <button onClick={() => editor.chain().focus().toggleItalic().run()}>
        Italic
      </button>
    </div>
  )
}

就是这么简单!在接下来的章节中,我们将深入学习每个部分。


6. 本章总结

在本章中,我们学习了:

✅ 核心概念

1. Tiptap 是什么

  • 无头的富文本编辑器框架
  • 基于 ProseMirror
  • 框架无关

2. 核心理念

  • 可扩展性
  • 类型安全
  • 声明式 API
  • 协同优先

3. 核心优势

  • 现代化的开发体验
  • 完全自定义的 UI
  • 丰富的扩展生态
  • 强大的协同编辑
  • 高性能
  • 类型安全

📊 对比其他编辑器

编辑器 适用场景
Tiptap 需要自定义 UI、协同编辑、现代前端项目
Draft.js React 项目,但已进入维护模式
Slate React 项目,需要底层控制
Quill 快速原型,需要预设 UI
TinyMCE 传统项目,需要开箱即用

🎯 适用场景

适合:

  • 自定义 UI 需求
  • 协同编辑应用
  • 现代前端项目
  • 高度定制需求
  • 长期维护项目

不适合:

  • 快速原型开发
  • 简单文本编辑
  • 不熟悉现代前端
  • 需要开箱即用的 UI

🔑 关键特性

  • 扩展系统:Nodes、Marks、Extensions
  • Commands:链式调用、类型安全
  • Schema:文档结构定义
  • 协同编辑:基于 Y.js 的 CRDT

8. 扩展阅读


最后欢迎大家一起来学习 企业级前端AI和基建项目实战!

期待下一章节!欢迎评论区交流技术!

相关推荐
关中老四1 小时前
【js/web甘特图插件MZGantt】如何使用外部弹框添加和修改任务(updRows方法使用说明)
前端·javascript·甘特图·甘特图插件
兆子龙1 小时前
Vite 打包优化实战:从 12.17M 到 7.95M 的瘦身之旅
javascript
小涛不学习1 小时前
WebSocket 技术详解(原理 + 使用 + 面试总结)
websocket·网络协议·面试
nunumaymax1 小时前
css实现元素和文字从右向左排列
前端·css
confiself2 小时前
A2UI实时渲染展示
开发语言·javascript·css
马士兵教育2 小时前
程序员空窗期如何解决?
人工智能·面试·职场和发展
草履虫建模2 小时前
面试常问 SQL 优化八股文总结:慢查询、索引失效、回表、覆盖索引一次搞懂
java·数据库·spring boot·sql·面试·职场和发展·数据库架构
yatum_20142 小时前
CentOS 7 集群 SSH 免密与主机名配置文档
linux·前端·网络