tiptap-vue-kit
v0.1.7
Published
基于 Tiptap 的 Vue 3 富文本编辑器套件,支持公式、Markdown / Word 导入
Maintainers
Readme
tiptap-vue-kit
面向 Vue 3 的富文本编辑器(基于 Tiptap)。通过插件注册 + defineKit() 打开图片、视频、公式、表格、Markdown / Word 导入等能力。
只读渲染(H5 / 微信)请使用独立包 tiptap-vue-kit-render,不要把本包直接塞进小程序。
相关转换包:
- tiptap-vue-kit-markdown — Markdown → HTML
- tiptap-vue-kit-docx — Word → HTML
特性
- 基础排版:标题、加粗/斜体/下划线/删除线、字号字体、颜色、高亮、对齐、缩进、行距
- 结构:无序/有序/任务列表、引用、代码块、分割线、链接、表格、分栏
- 媒体:图片 / 视频(宿主接入上传;浮框对齐、环绕、拖拽缩放)
- 公式:行内 / 块级(
$...$/$$...$$与工具栏) - 效率:格式刷、查找替换、Markdown 插入、Word 导入(可选 MathType 服务)
- UI:浮层基于 shadcn-vue
- 可选:AI 补全、字数限制、自定义工具栏 / 菜单栏
安装
npm install tiptap-vue-kit vue katextiptap-vue-kit-markdown、tiptap-vue-kit-docx、tiptap-vue-kit-render 会作为依赖随编辑器带上(按需在业务里直接 import 亦可)。
注册插件
import { createApp } from 'vue'
import { TiptapVueKit } from 'tiptap-vue-kit'
import 'tiptap-vue-kit/style.css'
import 'katex/dist/katex.min.css'
createApp(App).use(TiptapVueKit).mount('#app')注册后可用 <RichEditor> / <rich-editor>。也可以不 use,按需导入组件。
最小集成示例
<script setup lang="ts">
import { ref } from 'vue'
import { RichEditor, defineKit } from 'tiptap-vue-kit'
const html = ref('<p>Hello</p>')
const kit = defineKit({
placeholder: '输入 / 打开命令菜单',
})
</script>
<template>
<RichEditor v-model="html" :kit="kit" />
</template>v-model绑定 HTML- 需要交给渲染包时,用组件 ref 调用
getJSON()
<script setup lang="ts">
import { ref } from 'vue'
import { RichEditor, defineKit } from 'tiptap-vue-kit'
import { toUniHtml } from 'tiptap-vue-kit-render'
const html = ref('<p></p>')
const kit = defineKit({})
const editorRef = ref<{ getJSON: () => unknown } | null>(null)
function previewForMp() {
const json = editorRef.value?.getJSON()
if (!json) return
const { html: out, media, warnings } = toUniHtml(json, { platform: 'mp' })
console.log(out, media, warnings)
}
</script>
<template>
<RichEditor ref="editorRef" v-model="html" :kit="kit" />
<button type="button" @click="previewForMp">预览小程序 HTML</button>
</template>Markdown 导入
工具栏「插入 Markdown」会打开对话框:粘贴或选择 .md,转为标题、列表、表格、任务、代码和公式后插入。
底层使用 tiptap-vue-kit-markdown;本包 re-export markdownToHtml:
import { markdownToHtml } from 'tiptap-vue-kit'
// 等价于 from 'tiptap-vue-kit-markdown'
const content = markdownToHtml(
'容器内 \\(O_2\\) 净增速率为 \\(a\\),且 \\(a=b>0\\)。',
{ decorateImages: true }, // 编辑器内插入时建议打开
)
editor.chain().focus().insertContent(content).run()支持的公式写法:$...$、$$...$$、\(...\)、\[...\](含双反斜杠形式)。> 等符号不会因 HTML 转义变成 >。
Word 导入与 MathType(可选)
默认走 tiptap-vue-kit-docx(OMML + 文本 LaTeX)。
若文档含 MathType OLE,可配置 Python 服务;未配置 apiUrl 时不会弹出 MathType 提示、也不会请求服务:
defineKit({
docx: {
mathtype: {
apiUrl: 'http://127.0.0.1:18765',
// askBeforeConvert: true,
// convertPath: '/api/v1/convert/docx',
// timeoutMs: 60000,
},
},
})服务说明:services/mathtype-converter。
完整示例(含图片上传):
import { defineKit, createLocalMediaUploader } from 'tiptap-vue-kit'
const kit = defineKit({
image: {
maxSize: 8 * 1024 * 1024,
upload: async (file) => {
const form = new FormData()
form.append('file', file)
const res = await fetch('/api/upload', { method: 'POST', body: form })
const json = await res.json()
return { src: json.url, alt: file.name }
},
},
docx: {
imageMode: 'auto', // 有 upload → Word 内图片走上传;否则 base64
mathtype: {
apiUrl: import.meta.env.VITE_MATHTYPE_API_URL,
},
},
})| docx.imageMode | 行为 |
|------------------|------|
| auto(默认) | 已配置 image.upload → 逐张上传;否则内联 base64 |
| base64 | 始终 base64 |
| upload | 强制上传;未配置 upload 时报错 |
图片 / 视频上传(宿主接入)
编辑器不内置 OSS。工具栏插入图片/视频时调用你传入的 KitMediaUploader。
| 字段 | 说明 |
|------|------|
| upload(file, ctx) | 宿主必填(除非 pick 直接返回已上传资源) |
| pick(ctx) | 可选;素材库 / 相机 / 填 URL |
| accept / maxSize / multiple / resizable / onError | 校验与交互 |
本地 Demo
defineKit({
image: createLocalMediaUploader('image'),
video: createLocalMediaUploader('video'),
})接到自有 API / OSS
defineKit({
image: {
accept: 'image/png,image/jpeg,image/webp,image/gif',
maxSize: 8 * 1024 * 1024,
upload: async (file) => {
const form = new FormData()
form.append('file', file)
const res = await fetch('/api/upload', { method: 'POST', body: form })
const json = await res.json()
return { src: json.url, alt: file.name }
},
onError: (err) => console.error(err),
},
video: {
accept: 'video/mp4,video/webm',
maxSize: 80 * 1024 * 1024,
upload: async (file) => uploadToOss(file),
},
})自定义选择器
image: {
pick: async () => {
const picked = await openMaterialLibrary()
if (!picked) return null
return { src: picked.cdnUrl, alt: picked.name }
},
}不传 image / video(或传 false)则工具栏不出现对应按钮。
媒体浮框与拖拽缩放
选中图片或视频后出现浮框:对齐、文字环绕、行内(仅图)、ALT、尺寸比例。四角拖拽写入 sizeMode: custom + width: Npx。resizable: false 可关闭。
自定义工具栏 / 菜单栏
// 只显示标题和字号
defineKit({ toolbar: { heading: true, fontSize: true } })
// 按数组顺序
defineKit({ toolbar: ['heading', '|', 'fontSize', 'markdown', 'importWord'] })
// 从默认栏关掉某几项
defineKit({ toolbar: { image: false, video: false, ai: false } })组件级覆盖(不用重建 kit):
<RichEditor
:kit="kit"
:toolbar="{ heading: true, fontSize: true, markdown: true }"
:menubar="['undo', 'redo', 'find', 'preview']"
/>| 传入 | 效果 |
|------|------|
| ['heading', 'fontSize'] | 只渲染这两项 |
| { heading: true } | 只渲染为 true 的项 |
| { image: false } | 默认栏去掉图片 |
| [] / hideToolbar | 隐藏格式栏 |
| menubar: true | 顶栏:撤销、重做、查找、预览、打印、全屏 |
完整工具项 id:undo redo heading fontSize fontFamily bold italic underline strike code subscript superscript color highlight alignLeft alignCenter alignRight indent outdent lineHeight bulletList orderedList taskList blockquote codeBlock hr table link columns image video inlineMath blockMath formatPainter clearFormat importWord markdown ai find preview print fullscreen。
查找与替换 / 格式刷 / 分栏
- 查找:
Cmd/Ctrl+F,无遮罩浮动面板,匹配高亮 - 格式刷:单击刷一次,双击连续刷,
Esc取消 - 分栏:H5 横排;小程序渲染时竖向堆叠并 warning
其它 defineKit 选项
| 选项 | 默认 | 说明 |
|------|------|------|
| placeholder | 提示文案 | 空文档占位 |
| characterLimit | 50000 | null 不限制 |
| mathematics | true | 公式能力 |
| toolbar / menubar | 见上 | 工具栏配置 |
| ai | false | { completions } |
| image / video | false | 上传配置 |
| docx | {} | Word / MathType / 图片模式 |
组件方法
RichEditor 暴露:
| 方法 / 属性 | 说明 |
|-------------|------|
| editor | Tiptap Editor 实例 |
| getJSON() | 文档 JSON(交给 render) |
| setHtml(html) | 设置 HTML |
| insertInlineMath / insertBlockMath | 插入公式 |
| insertMarkdown | 插入 Markdown 转换结果 |
和渲染包一起用
import { toUniHtml } from 'tiptap-vue-kit-render'
const json = editorRef.value.getJSON()
const { html, warnings } = toUniHtml(json, { platform: 'mp' })- Web / H5:
RichContent或platform: 'h5' - 微信:
UniRichContent,传 JSON,不要直接塞编辑器 HTML
开发与发布
# 仓库根目录
npm install
npm run build -w tiptap-vue-kit
npm publish -w tiptap-vue-kit --access public本地联调:npm run dev(apps/demo)。
许可证
MIT
