Vue中使用Tiptap富文本編輯器的方法指南
前言
Tiptap 是一款基于 ProseMirror 構(gòu)建的現(xiàn)代化富文本編輯器,以其高度可定制性和插件化架構(gòu)在 Vue/React 生態(tài)中備受青睞。本文將系統(tǒng)介紹如何在 Vue 3 項(xiàng)目中集成 Tiptap,并實(shí)現(xiàn)基礎(chǔ)功能與進(jìn)階擴(kuò)展。
一、環(huán)境準(zhǔn)備與基礎(chǔ)集成
1. 安裝依賴
npm install @tiptap/vue-3 @tiptap/starter-kit
@tiptap/vue-3:Vue 3 專用適配器@tiptap/starter-kit:基礎(chǔ)功能包(含標(biāo)題、列表、撤銷等)
2. 創(chuàng)建編輯器組件
<template>
<div class="editor-container">
<editor-content :editor="editor" class="editor" />
</div>
</template>
<script setup>
import { onBeforeUnmount, ref } from 'vue'
import { Editor, EditorContent } from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit'
const editor = ref(null)
onMounted(() => {
editor.value = new Editor({
extensions: [StarterKit],
content: '<p>歡迎使用 Tiptap 編輯器</p>',
})
})
onBeforeUnmount(() => {
editor.value?.destroy()
})
</script>
<style scoped>
.editor {
border: 1px solid #ddd;
padding: 16px;
min-height: 300px;
border-radius: 4px;
}
</style>二、核心功能擴(kuò)展
1. 常用擴(kuò)展插件
| 插件名稱 | 安裝命令 | 功能說(shuō)明 |
|---|---|---|
@tiptap/extension-link | npm install @tiptap/extension-link | 鏈接插入與編輯 |
@tiptap/extension-image | npm install @tiptap/extension-image | 圖片上傳(需自定義上傳邏輯) |
@tiptap/extension-table | npm install @tiptap/extension-table | 表格操作(含行列增刪) |
@tiptap/extension-code-block-lowlight | npm install @tiptap/extension-code-block-lowlight lowlight | 代碼高亮(需配合語(yǔ)法庫(kù)) |
2. 完整擴(kuò)展配置示例
import Link from '@tiptap/extension-link'
import Image from '@tiptap/extension-image'
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 CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
import { lowlight } from 'lowlight/lib/common'
const editor = new Editor({
extensions: [
StarterKit,
Link.configure({
openOnClick: false, // 禁用點(diǎn)擊跳轉(zhuǎn)
validate: href => /^https?:\/\//.test(href), // 驗(yàn)證URL格式
}),
Image.configure({
allowBase64: true, // 允許base64圖片
HTMLAttributes: {
class: 'editor-image',
},
}),
Table.configure({
resizable: true,
}),
TableRow,
TableCell,
TableHeader,
CodeBlockLowlight.configure({
lowlight,
}),
],
content: '<p>開(kāi)始編輯...</p>',
})三、進(jìn)階功能實(shí)現(xiàn)
1. 自定義上傳圖片
import { uploadImage } from '@/api/upload' // 假設(shè)存在上傳接口
const editor = new Editor({
extensions: [
Image.configure({
inline: true, // 行內(nèi)圖片
async onUpload({ file }) {
const formData = new FormData()
formData.append('file', file)
const { data } = await uploadImage(formData)
return data.url // 返回圖片URL
},
}),
],
})2. 實(shí)時(shí)字?jǐn)?shù)統(tǒng)計(jì)
<template>
<div>
<editor-content :editor="editor" />
<div class="word-count">當(dāng)前字?jǐn)?shù):{{ characterCount }}</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import CharacterCount from '@tiptap/extension-character-count'
const editor = new Editor({
extensions: [
StarterKit,
CharacterCount.configure({
limit: 1000, // 限制1000字
}),
],
})
const characterCount = computed(() => editor.storage.characterCount.characters())
</script>3. 自定義工具欄
<template>
<div class="toolbar">
<button @click="editor.chain().focus().toggleBold().run()" :disabled="!editor.can().chain().focus().toggleBold().run()">
<strong>B</strong>
</button>
<button @click="editor.chain().focus().toggleItalic().run()" :disabled="!editor.can().chain().focus().toggleItalic().run()">
<em>I</em>
</button>
<!-- 更多按鈕... -->
</div>
<editor-content :editor="editor" />
</template>四、性能優(yōu)化與最佳實(shí)踐
- 資源清理:在組件卸載時(shí)調(diào)用
editor.destroy() - 懶加載:對(duì)非首屏編輯器使用動(dòng)態(tài)導(dǎo)入
- 插件管理:按需加載插件,避免過(guò)度擴(kuò)展
- 內(nèi)容安全:對(duì)用戶輸入進(jìn)行XSS過(guò)濾(Tiptap默認(rèn)已轉(zhuǎn)義)
五、常見(jiàn)問(wèn)題解決
Vue 3組合式API適配使用
ref包裹編輯器實(shí)例,并通過(guò)onMounted/onBeforeUnmount管理生命周期TypeScript支持安裝類型定義包:
npm install --save-dev @tiptap/pm @tiptap/vue-3
并在
tsconfig.json中添加:{ "compilerOptions": { "types": ["@tiptap/pm"] } }SSR兼容性在服務(wù)端渲染時(shí)需跳過(guò)編輯器初始化,通過(guò)
isClient判斷:import { isClient } from '@vueuse/core' if (isClient) { editor = new Editor({ /* ... */ }) }六、插件生態(tài)推薦
插件名稱 功能說(shuō)明 官方文檔 @tiptap/extension-history撤銷/重做歷史記錄 History Extension @tiptap/extension-markdownMarkdown語(yǔ)法支持 Markdown Extension tiptap-extension-global-drag-handle全局拖拽把手(需單獨(dú)安裝) Global Drag Handle 總結(jié)
Tiptap 通過(guò)其模塊化設(shè)計(jì),允許開(kāi)發(fā)者從基礎(chǔ)功能開(kāi)始逐步構(gòu)建復(fù)雜編輯器。在實(shí)際項(xiàng)目中,建議:
按需引入插件,避免過(guò)度擴(kuò)展
封裝自定義工具欄組件,提升可維護(hù)性
對(duì)用戶輸入內(nèi)容進(jìn)行二次校驗(yàn),確保數(shù)據(jù)安全
通過(guò)本文的實(shí)踐指南,開(kāi)發(fā)者可以快速掌握 Tiptap 的核心用法,并根據(jù)業(yè)務(wù)需求進(jìn)行深度定制。
到此這篇關(guān)于Vue中使用Tiptap富文本編輯器的文章就介紹到這了,更多相關(guān)Vue用Tiptap富文本編輯器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue頁(yè)面之間相互傳值的實(shí)現(xiàn)方式
這篇文章主要介紹了vue頁(yè)面之間相互傳值的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2026-03-03
巧妙運(yùn)用v-model實(shí)現(xiàn)父子組件傳值的方法示例
這篇文章主要介紹了巧妙運(yùn)用v-model實(shí)現(xiàn)父子組件傳值的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-04-04
vue pdf二次封裝解決無(wú)法顯示中文問(wèn)題方法詳解
這篇文章主要為大家介紹了vue pdf二次封裝解決無(wú)法顯示中文問(wèn)題方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
vue+electron 自動(dòng)更新的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue+electron 自動(dòng)更新的實(shí)現(xiàn)代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-02-02
Vue中實(shí)現(xiàn)滾動(dòng)加載與無(wú)限滾動(dòng)
本文主要介紹了Vue中實(shí)現(xiàn)滾動(dòng)加載與無(wú)限滾動(dòng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
Vue3的setup在el-tab中動(dòng)態(tài)加載組件的方法
公司某項(xiàng)目需求在頁(yè)面顯示的組件是根據(jù)角色變化而變化的,怎么實(shí)現(xiàn)這個(gè)效果呢,下面小編給大家介紹下Vue3的setup在el-tab中動(dòng)態(tài)加載組件的方法,需要的朋友可以參考下2022-11-11
nuxt 頁(yè)面路由配置,主頁(yè)輪播組件開(kāi)發(fā)操作
這篇文章主要介紹了nuxt 頁(yè)面路由配置,主頁(yè)輪播組件開(kāi)發(fā)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
vue同時(shí)觸發(fā)兩個(gè)函數(shù)的情況
這篇文章主要介紹了vue同時(shí)觸發(fā)兩個(gè)函數(shù)的情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04

