目錄
🧰 技術棧
📦 所需依賴
📁 文件結構
🧱 編輯器組件實現(components/Editor.vue)
? 常用操作指令
🧠 小貼士
🧩 Tiptap 擴展功能使用說明(含快捷鍵與命令)
🔹 StarterKit(基礎功能集)
🔹 Link(鏈接)
🔹 Table(表格)
🔹 CodeBlockLowlight(代碼塊 + 語法高亮)
🔹 Placeholder(占位提示)
🔹 Image(圖片上傳)
🔹 自定義 Attachment(附件上傳)
tiptap collaborative 實時協作
網絡實時通信
WebSocket 推薦
WebSocket 后端
多個服務器
顯示光標
離線支持
🔗 推薦鏈接
? 總結
本文是針對零基礎前端開發者撰寫,目的是快速上手并集成一個功能完整的富文本編輯器(Tiptap)到你的 Vue 項目中。
🧰 技術棧
-
Vue 3 +
<script setup>
-
Tiptap(基于 ProseMirror)
-
多種 Tiptap 插件(Extension)支持
📦 所需依賴
npm install @tiptap/vue-3 @tiptap/starter-kit \@tiptap/extension-link \@tiptap/extension-table \@tiptap/extension-table-row \@tiptap/extension-table-cell \@tiptap/extension-table-header \@tiptap/extension-placeholder \@tiptap/extension-code-block-lowlight \@tiptap/extension-image \@tiptap/extension-character-count \lowlight
📁 文件結構
src/
├─ components/
│ └─ Editor.vue # 編輯器組件
└─ App.vue
🧱 編輯器組件實現(components/Editor.vue)
<template><editor-content :editor="editor" class="editor" />
</template><script setup>
import { onBeforeUnmount } from 'vue'
import { Editor, EditorContent } from '@tiptap/vue-3'import StarterKit from '@tiptap/starter-kit'
import Link from '@tiptap/extension-link'
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 Placeholder from '@tiptap/extension-placeholder'
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
import { lowlight } from 'lowlight/lib/common'
import Image from '@tiptap/extension-image'
import CharacterCount from '@tiptap/extension-character-count'const editor = new Editor({extensions: [StarterKit,Link,Placeholder.configure({ placeholder: '請輸入內容…' }),Table.configure({ resizable: true }),TableRow,TableCell,TableHeader,CodeBlockLowlight.configure({ lowlight }),Image,CharacterCount.configure({ limit: 500 }),],content: '<p>Hello Tiptap!</p>',
})onBeforeUnmount(() => {editor.destroy()
})
</script><style scoped>
.editor {border: 1px solid #ccc;padding: 16px;border-radius: 8px;min-height: 200px;
}
</style>
? 常用操作指令
-
獲取 HTML 內容:
editor.getHTML()
-
獲取 JSON 內容:
editor.getJSON()
-
執行命令示例(如設置為加粗):
editor.commands.toggleBold()
🧠 小貼士
-
所有 Extension 都可以配置和拓展,官方文檔中提供了詳細 API。
-
菜單欄需要你自行實現,可以通過組合
editor.commands
來制作按鈕。 -
可自定義 CSS 樣式,支持暗色模式、響應式布局等。
🧩 Tiptap 擴展功能使用說明(含快捷鍵與命令)
以下內容將詳細列出各個 Tiptap 擴展的使用方式,包括:
-
如何引入
-
如何注冊(放進 extensions)
-
快捷鍵(如有)
-
使用 editor.commands 如何觸發
🔹 StarterKit(基礎功能集)
-
引入:
import StarterKit from '@tiptap/starter-kit'
-
注冊:
extensions: [ StarterKit ]
-
快捷鍵(默認):
-
加粗:
Mod-b
-
斜體:
Mod-i
-
標題:
Ctrl-Alt-1~6
-
列表:
Shift-Ctrl-8/9
-
-
命令示例:
editor.commands.toggleBold()
editor.commands.toggleItalic()
editor.commands.toggleHeading({ level: 2 })
editor.commands.toggleBulletList()
🔹 Link(鏈接)
-
引入:
import Link from '@tiptap/extension-link'
-
注冊:
extensions: [ Link.configure({ openOnClick: true }) ]
-
快捷鍵:無默認
-
命令示例:
editor.commands.setLink({ href: 'https://example.com' })
editor.commands.unsetLink()
🔹 Table(表格)
-
引入:
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'
-
注冊:
extensions: [Table.configure({ resizable: true }),TableRow,TableHeader,TableCell,
]
-
快捷鍵:無默認
-
命令示例:
editor.commands.insertTable({ rows: 3, cols: 3 })
editor.commands.addColumnAfter()
editor.commands.deleteTable()
🔹 CodeBlockLowlight(代碼塊 + 語法高亮)
-
引入:
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
import { lowlight } from 'lowlight/lib/common'
-
注冊:
extensions: [CodeBlockLowlight.configure({ lowlight }),
]
-
快捷鍵:
-
`Ctrl + Shift + ``
-
-
命令示例:
editor.commands.toggleCodeBlock()
🔹 Placeholder(占位提示)
-
引入:
import Placeholder from '@tiptap/extension-placeholder'
-
注冊:
extensions: [Placeholder.configure({ placeholder: '請輸入內容…' })
]
-
快捷鍵:無
-
命令示例:無,主要是展示效果
🔹 Image(圖片上傳)
-
引入:
import Image from '@tiptap/extension-image'
-
注冊:
extensions: [ Image ]
-
快捷鍵:無
-
命令示例:
editor.commands.setImage({ src: 'https://example.com/image.jpg' })
通常結合
<input type="file">
使用,將圖片上傳到服務器后獲取鏈接插入。
🔹 自定義 Attachment(附件上傳)
Tiptap 沒有內建“附件”類型,可自定義擴展:
-
引入(自定義 Node):
async handleFileUpload(e) {const file = e.target.files[0];if (!file) return;try {// 1. 上傳文件到服務器(假設 uploadImage 支持所有類型或調整為通用上傳函數)const url = await this.uploadImage(file);// 2. 根據文件類型插入內容if (file.type.startsWith('image/')) {// 插入圖片this.editor.chain().focus().setImage({ src: url }).run();} else {// 非圖片類型插入“附件”文本(可帶鏈接)this.editor.chain().focus().insertContent('附件').run();// 如需插入鏈接:this.editor.chain().focus().insertContent(`<a href="${url}">附件</a>`).run();}} catch (error) {console.error("上傳失敗:", error);alert("上傳失敗,請重試");} finally {e.target.value = null;}
}
-
快捷鍵:無
-
命令示例:
editor.commands.insertContent({type: 'attachment',attrs: {href: 'https://example.com/file.pdf',filename: '報告文件.pdf',},
})
上傳方式與圖片類似,使用 file input 或拖拽上傳后插入鏈接。
tiptap collaborative 實時協作
tiptap?支持實時協作、讓不同設備之間的同步和離線工作。通過與?Y.js?配合使用無需多少代碼即可實現多人在線實時協作,不過在大部分的實踐工作中,實時協作并不是一個強需求。
網絡實時通信
WebRTC僅使用服務器讓各個客戶端(瀏覽器)擊行相互通訊。服務器并不參與數據的傳輸。
安裝依賴項:
npm install @tiptap/extension-collaboration yjs y-webrtc y-prosemirror
然后創建一個 Y 文檔,并注冊到 Tiptap:
import { WebrtcProvider } from 'y-webrtc'// A new Y document
const ydoc = new Y.Doc()
// Registered with a WebRTC provider
const provider = new WebrtcProvider('example-document', ydoc)const editor = new Editor({extensions: [StarterKit.configure({// The Collaboration extension comes with its own history handlinghistory: false,}),// Register the document with TiptapCollaboration.configure({document: ydoc,}),],
})
到此為止你就可以讓不同的用戶進行實時協作了,它是如何運行的呢?WebRTC程序通過公共服務器將客戶端連接在一起,服務器并不同步實際的更改,然而這個也有兩個缺點。
1,瀏覽器拒絕連接太多客戶端,對于同一文檔中超過 100+ 個并發客戶端,它不能很好的支持。
2,服務器沒有參與文檔記錄的更改,因為WebRTC信令服務器不會收到更改,因此不知道文檔中的內容。
如果你想更深入地研究,請前往GitHub上的Y WebRTC存儲庫
WebSocket 推薦
對于大多數情況,tiptap建議使用 WebSocket ,因為它更靈活,也可以很好地擴展。為了更容易使用,tiptap發布了Hocuspocus作為Tiptap的官方后端程序。
對于客戶端示例幾乎相同,只不過驅動程序不同。首先,讓我們安裝依賴項:
npm install @tiptap/extension-collaboration @hocuspocus/provider y-prosemirror
然后向 Tiptap 注冊 WebSocket 供應程序:
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import Collaboration from '@tiptap/extension-collaboration'
import { HocuspocusProvider } from '@hocuspocus/provider'// Set up the Hocuspocus WebSocket provider
const provider = new HocuspocusProvider({url: 'ws://127.0.0.1:1234',name: 'example-document',
})const editor = new Editor({extensions: [StarterKit.configure({// The Collaboration extension comes with its own history handlinghistory: false,}),// Register the document with TiptapCollaboration.configure({document: provider.document,}),],
})
如你所見此示例不是開箱即用的。它需要配置為與WebSocket服務器通信,因此需要安裝WebSocket 后端程序Hocuspocus。
WebSocket 后端
為了使服務器部分盡可能簡單,tiptap提供了一個node.js的服務器包 Hocuspocus。它是一個靈活的 Node.js 包,可用于構建后端。
下面的命令用來啟動這個服務:
npx @hocuspocus/cli --port 1234 --sqlite
運行 Hocuspocus 命令行,啟動偵聽1234端口并將更改存儲在內存中(一旦停止命令,它就會消失),輸出如下所示:
Hocuspocus v1.0.0 running at:> HTTP: http://127.0.0.1:1234
> WebSocket: ws://127.0.0.1:1234Ready.
嘗試在瀏覽器中打開 http://127.0.0.1:1234 網址,如果一切運行正常,你應該會看到一個純文本。
然后返回 Tiptap 編輯器并F5刷新網頁,它將連接到 Hocuspocus WebSocket 服務器,這時就可以與其他用戶進行實時協作了。
多個服務器
你可以注冊多個服務器保證服務的穩定,當一個服務器宕機客戶端將連接另外一個服務器
new WebrtcProvider('example-document', ydoc)
new HocuspocusProvider({url: 'ws://127.0.0.1:1234',name: 'example-document',document: ydoc,
})
顯示光標
當多個人進行在線編輯,你可以設置每個人的昵稱顯示在編輯器光標位置
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import Collaboration from '@tiptap/extension-collaboration'
import CollaborationCursor from '@tiptap/extension-collaboration-cursor'
import { HocuspocusProvider } from '@hocuspocus/provider'// Set up the Hocuspocus WebSocket provider
const provider = new HocuspocusProvider({url: 'ws://127.0.0.1:1234',name: 'example-document',
})const editor = new Editor({extensions: [StarterKit.configure({// The Collaboration extension comes with its own history handlinghistory: false,}),Collaboration.configure({document: provider.document,}),// Register the collaboration cursor extensionCollaborationCursor.configure({provider: provider,user: {name: 'Cyndi Lauper',color: '#f783ac',},}),],
})
離線支持
基于Y IndexedDB 你可以實現關閉瀏覽器后所有更改都將存儲在瀏覽器中,下次聯機時,WebSocket 提供程序將嘗試查找連接并最終同步更改。
如需添加更多擴展(如任務列表、縮進、emoji 等),可以繼續在此格式基礎上擴展。
🔗 推薦鏈接
- tiptap 自定義擴展 | 摳丁客
-
官方網站:Tiptap - Dev Toolkit Editor Suite
-
GitHub:https://github.com/ueberdosis/tiptap
-
ProseMirror 引擎:ProseMirror
? 總結
本文總結了一個基于 Vue3 + Tiptap 的富文本編輯器完整實現過程,涵蓋依賴安裝、擴展配置、編輯器初始化與常用操作,適合新手開發者快速上手。如果你希望快速搭建一個功能完整的編輯器,完全可以直接復制本文結構并根據需求調整內容。