Vue 中使用 Tiptap 富文本编辑器的完整指南

Tiptap 是一款基于 ProseMirror 构建的现代化富文本编辑器,以其高度可定制性和插件化架构在 Vue/React 生态中备受青睐。本文将系统介绍如何在 Vue 3 项目中集成 Tiptap,并实现基础功能与进阶扩展。

一、环境准备与基础集成

1. 安装依赖

复制代码
npm install @tiptap/vue-3 @tiptap/starter-kit
  • @tiptap/vue-3:Vue 3 专用适配器
  • @tiptap/starter-kit:基础功能包(含标题、列表、撤销等)

2. 创建编辑器组件

复制代码
<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>

二、核心功能扩展

1. 常用扩展插件

插件名称 安装命令 功能说明
@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 代码高亮(需配合语法库)

2. 完整扩展配置示例

复制代码
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, // 禁用点击跳转
      validate: href => /^https?:\/\//.test(href), // 验证URL格式
    }),
    Image.configure({
      allowBase64: true, // 允许base64图片
      HTMLAttributes: {
        class: 'editor-image',
      },
    }),
    Table.configure({
      resizable: true,
    }),
    TableRow,
    TableCell,
    TableHeader,
    CodeBlockLowlight.configure({
      lowlight,
    }),
  ],
  content: '<p>开始编辑...</p>',
})

三、进阶功能实现

1. 自定义上传图片

复制代码
import { uploadImage } from '@/api/upload' // 假设存在上传接口
const editor = new Editor({
  extensions: [
    Image.configure({
      inline: true, // 行内图片
      async onUpload({ file }) {
        const formData = new FormData()
        formData.append('file', file)
        const { data } = await uploadImage(formData)
        return data.url // 返回图片URL
      },
    }),
  ],
})

2. 实时字数统计

复制代码
<template>
  <div>
    <editor-content :editor="editor" />
    <div class="word-count">当前字数:{{ 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>

四、性能优化与最佳实践

  1. 资源清理 :在组件卸载时调用 editor.destroy()
  2. 懒加载:对非首屏编辑器使用动态导入
  3. 插件管理:按需加载插件,避免过度扩展
  4. 内容安全:对用户输入进行XSS过滤(Tiptap默认已转义)

五、常见问题解决

  1. Vue 3组合式API适配

    使用 ref 包裹编辑器实例,并通过 onMounted/onBeforeUnmount 管理生命周期

  2. TypeScript支持

    安装类型定义包:

    复制代码
    npm install --save-dev @tiptap/pm @tiptap/vue-3

    并在 tsconfig.json 中添加:

    复制代码
    {
      "compilerOptions": {
        "types": ["@tiptap/pm"]
      }
    }
  3. SSR兼容性

    在服务端渲染时需跳过编辑器初始化,通过 isClient 判断:

    复制代码
    import { isClient } from '@vueuse/core'
    if (isClient) {
      editor = new Editor({ /* ... */ })
    }
    复制代码

    六、插件生态推荐

    插件名称 功能说明 官方文档
    @tiptap/extension-history 撤销/重做历史记录 History Extension
    @tiptap/extension-markdown Markdown语法支持 Markdown Extension
    tiptap-extension-global-drag-handle 全局拖拽把手(需单独安装) Global Drag Handle

    总结

    Tiptap 通过其模块化设计,允许开发者从基础功能开始逐步构建复杂编辑器。在实际项目中,建议:

    1. 按需引入插件,避免过度扩展
    2. 封装自定义工具栏组件,提升可维护性
    3. 对用户输入内容进行二次校验,确保数据安全

    通过本文的实践指南,开发者可以快速掌握 Tiptap 的核心用法,并根据业务需求进行深度定制。

相关推荐
css趣多多2 小时前
地图快速上手
前端
zhengfei6112 小时前
面向攻击性安全专业人员的一体化浏览器扩展程序[特殊字符]
前端·chrome·safari
码丁_1172 小时前
为什么前端需要做优化?
前端
Mr Xu_3 小时前
告别硬编码:前端项目中配置驱动的实战优化指南
前端·javascript·数据结构
Byron07073 小时前
从 0 到 1 搭建 Vue 前端工程化体系:提效、提质、降本实战落地
前端·javascript·vue.js
哆啦code梦3 小时前
前端存储三剑客:localStorage、sessionStorage与Cookie解析
前端·前端存储
zhengfei6113 小时前
【AI平台】- 基于大模型的知识库与知识图谱智能体开发平台
vue.js·语言模型·langchain·知识图谱·多分类
徐小夕@趣谈前端3 小时前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
Data_Journal4 小时前
如何使用 Python 解析 JSON 数据
大数据·开发语言·前端·数据库·人工智能·php