Tiptap 中如何自定义图片上传逻辑?

端木丽珍 阅读 22

我用 Tiptap 做富文本编辑器,想替换默认的图片插入方式,改成上传到自己的服务器。但文档里没找到清晰的例子,试了扩展 Image 节点也不生效。

现在点插入图片还是直接贴 URL,我想改成弹出文件选择框,然后走 axios.post('/upload') 上传。有谁搞过类似的吗?

import { Editor } from '@tiptap/vue-3'
import Image from '@tiptap/extension-image'

const editor = new Editor({
  extensions: [
    Image.configure({
      // 这里怎么拦截点击事件并触发上传?
    })
  ]
})
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
长孙芸菡
Tiptap 的 Image 扩展只负责渲染图片,不负责"怎么获取图片"。默认行为是直接让你填 URL,所以你想做文件上传需要自己写触发逻辑。

最直接的做法是在编辑器外部搞个隐藏的 file input,然后通过自定义命令把上传后的 URL 插进去:

import { Editor } from '@tiptap/vue-3'
import Image from '@tiptap/extension-image'
import axios from 'axios'

const editor = new Editor({
extensions: [
Image.configure({
inline: true,
allowBase64: true,
})
],
})

// 上传函数
const handleImageUpload = async (event) => {
const file = event.target.files[0]
if (!file) return

const formData = new FormData()
formData.append('file', file)

try {
const res = await axios.post('/upload', formData)
const imageUrl = res.data.url

// 关键:插入图片到编辑器
editor.value.chain().focus().setImage({ src: imageUrl }).run()
} catch (err) {
console.error('上传失败', err)
}

// 清空 input,避免重复选择同一文件不触发 change
event.target.value = ''
}


然后在模板里放个隐藏的 input 和触发按钮:

<input 
type="file"
accept="image/*"
style="display: none"
ref="fileInput"
@change="handleImageUpload"
>
<button @click="$refs.fileInput.click()">上传图片</button>


如果你想在编辑器内部点击某个按钮触发上传,可以在 Tiptap 的 bubble menu 或者 floating menu 里加,或者直接用 editor 暴露的命令:

// 在工具栏按钮点击时
const triggerUpload = () => {
document.querySelector('input[type="file"]').click()
}


还有个坑提醒你:Tiptap 2.x 的写法是 setImage,不是旧版本的 setImage 或者 insertImage,别搞错了。

如果你的后端还没搭好测试,可以先用 allowBase64: true 然后直接读 FileReader 转成 base64 塞进去,先跑通流程再说。
点赞
2026-03-19 20:02