最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue中使用Tiptap富文本編輯器的方法指南

 更新時(shí)間:2026年02月27日 10:25:35   作者:Byron0707  
Tiptap是一個(gè)無(wú)頭(headless)的富文本編輯器框架,專為?Web?工匠設(shè)計(jì),它提供了高度可定制和可擴(kuò)展的編輯器功能,適用于各種前端框架,這篇文章主要介紹了Vue中使用Tiptap富文本編輯器的相關(guān)資料,需要的朋友可以參考下

前言

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-linknpm install @tiptap/extension-link鏈接插入與編輯
@tiptap/extension-imagenpm install @tiptap/extension-image圖片上傳(需自定義上傳邏輯)
@tiptap/extension-tablenpm install @tiptap/extension-table表格操作(含行列增刪)
@tiptap/extension-code-block-lowlightnpm 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)方式

    這篇文章主要介紹了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)父子組件傳值的方法示例

    這篇文章主要介紹了巧妙運(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)題方法詳解

    這篇文章主要為大家介紹了vue pdf二次封裝解決無(wú)法顯示中文問(wèn)題方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • vue+electron 自動(dòng)更新的實(shí)現(xiàn)代碼

    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)

    本文主要介紹了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)加載組件的方法

    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
  • vue?父子組件共用mixins的注意點(diǎn)

    vue?父子組件共用mixins的注意點(diǎn)

    這篇文章主要介紹了vue?父子組件共用mixins的注意點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue實(shí)現(xiàn)圖片驗(yàn)證碼生成

    Vue實(shí)現(xiàn)圖片驗(yàn)證碼生成

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)圖片驗(yàn)證碼生成,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • nuxt 頁(yè)面路由配置,主頁(yè)輪播組件開(kāi)發(fā)操作

    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ù)的情況

    這篇文章主要介紹了vue同時(shí)觸發(fā)兩個(gè)函數(shù)的情況,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04

最新評(píng)論

龙游县| 永仁县| 九江市| 尤溪县| 板桥市| 进贤县| 婺源县| 榆社县| 和田市| 南充市| 苍溪县| 威信县| 阿拉善盟| 新巴尔虎右旗| 龙州县| 乌鲁木齐市| 海安县| 茌平县| 池州市| 靖边县| 宣威市| 鹤壁市| 双牌县| 红桥区| 金山区| 新巴尔虎右旗| 和龙市| 凤阳县| 宁河县| 剑川县| 溧水县| 康定县| 庆城县| 丹江口市| 新巴尔虎右旗| 芜湖市| 铜川市| 青浦区| 稷山县| 紫阳县| 扎鲁特旗|