Tiptap 无头富文本编辑器指南:3 步跑通你的自定义编辑器
2026/9/1 13:48:56 网站建设 项目流程

Tiptap 无头富文本编辑器指南:3 步跑通你的自定义编辑器

【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap

做内容类产品时,你可能遇到过这样的局面:评论框想加个加粗,文档编辑要标题、列表和引用,客户又提出把工具栏挪个位置。如果选的是 UI 和逻辑焊死的编辑器,每次改样式都得去抠它的内部代码。Tiptap 走的是另一条路——它是一个基于 ProseMirror 的无头富文本编辑器(headless rich text editor):核心只负责内容模型、状态和编辑逻辑,按钮、工具栏、皮肤全由你自己搭。

打个比方:Tiptap 像一台没有外壳的"编辑引擎",你负责给它装什么外壳,它负责把编辑这件事做对。这样换来的是"核心逻辑不变,界面千变万化",同一套扩展可以同时挂在 Vue 后台和 React 前台里。

项目速览:Tiptap 是什么、适合谁

一句话定位核心特性清单适用与不适用场景
无头、跨框架、靠扩展拼装能力的富文本编辑器基于 ProseMirror(README 提到该库已用于 New York Times、The Guardian、Atlassian 等,见 packages/core/README.md);不含任何内置 UI;官方 + 社区共 100+ 扩展(README);Vue 2/3、React、原生 JS 三种接入方式;命令链 API;Yjs + Hocuspocus 开源协作;MIT 协议✅ 需要深度定制编辑界面、多框架复用编辑核心、要做协同编辑的项目;❌ 只需要一个简单评论框、或想要开箱即用工具栏 UI 的场景

核心概念速览:3 个词看懂 Tiptap 的分层

  • Extension(扩展):像手机的应用商店。加粗、链接、表格、撤销……每个功能都是一个独立扩展,编辑器就是"核心 + 一份扩展清单"。用不上的功能不注册即可,不存在"背着一堆用不上的代码"。
  • Node 与 Mark(节点与标记):文档是一棵节点树。Node 是块级结构(段落、标题、代码块),Mark 是包在文字上的样式(加粗、斜体、行内代码)。理解这一对,就理解了 Tiptap 里 90% 的概念。
  • 命令链(Command Chain):编辑操作像流水线一样串起来。editor.chain().focus().toggleBold().run()读起来就是"聚焦,然后切换加粗,执行",比分别调用多个 API 再手动同步状态清爽得多。

快速上手:2 条命令装好,10 行代码出第一个编辑器 🚀

先安装核心依赖和框架适配器(以 Vue 3 为例,React 把最后一行换成@tiptap/react):

npm i @tiptap/core @tiptap/starter-kit @tiptap/vue-3

StarterKit 是官方打包的基础扩展集,包含加粗、斜体、标题、列表、引用、撤销重做等(见 packages/starter-kit/src/starter-kit.ts)。最小可用配置:

import { useEditor, EditorContent } from '@tiptap/vue-3' import StarterKit from '@tiptap/starter-kit' const editor = useEditor({ extensions: [StarterKit], content: '<p>你好,Tiptap</p>', })

模板里放一个<EditorContent :editor="editor" />,页面上就会出现一个可编辑的contenteditable区域,能打字、能换行。工具栏需要你自己写几个按钮,通过editor.chain().toggleBold().run()之类的命令去驱动。

建议在项目里这样组织目录,后面加自定义扩展不慌:

src/ └── editor/ ├── extensions/ # 自定义 Node / Mark / Extension ├── components/ # 工具栏等 UI 组件 └── useMyEditor.ts # 编辑器实例与扩展配置

跑通后预期效果:编辑区可正常输入;editor.getHTML()/editor.getJSON()能拿到结构化内容;给 StarterKit 传configure({ codeBlock: false })即可按需关掉某个功能。

深入解析:3 个真正有价值的技术点 🔍

扩展机制:能力是"注册制"的

为什么重要:它决定了编辑器能不能"长"成业务需要的样子。原理一句话:所有扩展统一继承自 Extension 基类,可以贡献 schema 节点、命令、按键映射、粘贴规则,互不干扰。关键代码:自己加一个自定义命令只需几十行:

import { Extension } from '@tiptap/core' export const QuoteAction = Extension.create({ name: 'quoteAction', addCommands() { return { toggleQuote: () => ({ commands }) => commands.toggleNode('blockquote'), } }, })

实际效果:任何组件、任何框架里都能editor.commands.toggleQuote(),功能调用和 UI 彻底解耦。

Node 定义:用一棵树描述你的文档结构

为什么重要:业务内容(病历、试卷、产品卡)往往不是"段落 + 标题"能表达的。原理一句话Node.create()声明节点的名字、分组、可包含内容和属性,再给个renderHTML就能进 schema。关键代码

import { Node } from '@tiptap/core' export const Figure = Node.create({ name: 'figure', group: 'block', content: 'image', addAttributes() { return { caption: { default: '' } } }, renderHTML({ HTMLAttributes }) { return ['figure', { ...HTMLAttributes, 'data-caption': HTMLAttributes.caption }, 0] }, })

实际效果:编辑器从此"认识"图片说明块,粘贴进来自动解析,序列化出去结构稳定,前后端共享同一份 JSON。

命令链:把多步操作合成一条流水线

为什么重要:复杂操作(聚焦 → 选中 → 加粗 → 设色)最容易在状态同步上翻车。原理一句话chain()把命令排成队列,前一步失败则后续自动跳过,run()时一次性派发事务。关键代码

editor .chain() .focus('end') .toggleBold() .run()

实际效果:工具栏、快捷键、AI 触发脚本可以共用同一套命令写法,不用再各自维护"当前选区是什么"。

避坑清单:4 个高频问题与解法 ⚠️

问题原因解法
编辑器空白、无法输入没注册 Document / Paragraph / Text 这些基础节点(手写扩展清单时漏了)直接用 StarterKit,或手动确保这三个节点在列
React/Next.js 下报window is not defined编辑器依赖 DOM,SSR 阶段提前创建了实例React 端设置immediatelyRender: false,只在客户端构建(见 packages/react/src/useEditor.ts)
从 Word/网页粘贴后样式混乱粘贴的 HTML 携带大量 schema 之外的标签和属性超出 schema 的内容解析时会被自动忽略;用扩展里的pasteRules做针对性清洗
大文档下保存接口被打爆onUpdate每次内容变更都会触发监听事件后自行防抖(如 300ms)再提交editor.getHTML()

性能与安全要点:只注册用得到的扩展,StarterKit 支持逐项关闭(codeBlock: false);历史栈长度可通过 undoRedo 配置控制;内容出前端后仍应在服务端再做一次净化,不要把编辑器 schema 当安全边界。

选型参考:Tiptap 和另外两条路怎么选

维度Tiptap手写 contenteditable商业编辑器(带现成工具栏)
开发成本中:核心现成,UI 自建高:粘贴、选区、移动端光标都要自己兜低:开箱即用
扩展性高:100+ 扩展 + 自由定制节点/视图完全自由但全要自己维护受限于厂商插件生态
多框架复用Vue 2/3、React、原生 JS 同一套核心天然无框架绑定,但代码难迁移各框架版本能力常不一致
协同编辑开源方案:Yjs + Hocuspocus 后端全靠自己多内置,但通常绑定其云服务
费用MIT 免费;部分高级 Pro 扩展需订阅(README)0按授权收费

什么情况下不建议选它:如果只是加个简单评论框,textarea 就够了,引入 Tiptap 是杀鸡用牛刀;如果团队只有两个人、要求两三天上线且没有前端精力自建工具栏,无头意味着第一天没有现成 UI,上手成本会被放大(可以参考 demos/ 里的现成页面抄结构);如果深度依赖某商业编辑器的云服务和私有插件,迁移收益要重新算账。

资源与展望

两个值得跟进的问题:一是 AI 生成内容与实时编辑如何共存——仓库里已经出现 ai-toolkit(含流式显示 streaming-reveal 相关实现),后续"边生成边可编辑"的体验还会怎么演进?二是多模态内容(音频、数学公式、图表)越来越多,节点扩展的边界会扩展到哪?

  • 核心源码:packages/core/src/
  • 官方示例站源码(可按需 fork 改):demos/
  • 入门教程示例:demos/src/Tutorials/
  • 协作编辑示例:demos/src/Examples/CollaborativeEditing/
  • 参与贡献:CONTRIBUTING.md

如果只想验证一下它值不值得进你的技术栈,最快的方式是:clone 仓库(git clone https://gitcode.com/GitHub_Trending/ti/tiptap),打开 demos 跑起来,挑一个最接近你业务的示例改两天——无头编辑器好不好用,两周之内就会有答案。

【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询