我希望你一切都好。 我正在开发一个像文本编辑器这样的媒体,我正在使用tiptap来实现它,并且我用react来实现它。 我陷入困境的一件事是上传图像。我想使用图像扩展或其他类似的东西来实现上传图像:
我想实现像这个系统这样的东西,但我无法接近解决方案。我搜索了一下,在 github 上找到了这个要点,但它并没有帮助我创建这样一个具有上传功能的扩展。 GITHUB 要点的链接
所以我需要你的帮助来实现这一目标。感谢您的帮助。
我终于找到了解决方案。 由于我将
tiptap
与 react
一起使用,并且我想让用户为图像编写标题,因此我决定使用 node view
扩展的 tiptap
功能。我将 addNodeView
添加到 Tiptap Image extension
来渲染我的组件(您需要扩展 Image
扩展。您可以在这里阅读有关扩展 Tiptap 扩展的信息):
addNodeView() {
return ReactNodeViewRenderer(ImageNode);
}
您可以在tiptap文档中阅读有关使用vue、react、vanilla js等在tiptap中创建和渲染节点视图的信息这里
在下一步中,我将
uploadImageHandler
添加到图像扩展的现有属性中。像这样:
addAttributes() {
return {
...this.parent(),
uploadImageHandler: { default: undefined },
};
}
因此,当您想使用
editor.commands.setImage
添加图像时,请向其中添加上传图像处理函数。并确保不要将 uploadImageHandler 添加到渲染元素的 HTML 属性中。因此,要做到这一点,你可以这样做(代码可能对你来说有点不同,因为我渲染与标题相关的 HTML):
renderHTML({ HTMLAttributes }) {
return [
'figure',
[
'img',
//This line removed uploadImageHandler from attributes
mergeAttributes(HTMLAttributes, { uploadImageHandler: undefined }),
],
['figcaption', HTMLAttributes.caption],
];
}
渲染组件的 props 中会有一个
node
属性,你可以这样访问属性:
const { src, alt, caption, uploadImageHandler } = node.attrs;
然后我添加了一个
useEffect
以在组件渲染后开始上传:
useEffect(() => {
//src can be a base64 string. Only upload the image when the src is base64
if (uploadImageHandler && src?.startsWith('data') && !isUploading) {
setIsUploading(true);
uploadImageHandler().then(imgUrl => {
//you can use updateAttributes from the component props
updateAttributes({ src: imgUrl });
setIsUploading(false);
});
}
}, [uploadImageHandler, src, isUploading]);
我的
uploadImageHandler
看起来像这样:
const uploadImageHandler = (imgSrc, imgType) => async () => {
const { Image, PreSignedURL } = await getPreSignedUrl(imgType);
await uploadImage({ url: PreSignedURL, image: imgSrc });
return Image;
};
我将此函数传递给
editor.commands.setImage
,如下所示:
editor.commands.setImage({
src: reader.result,
uploadImageHandler: uploadImageHandler(reader.result, imageFile.type),
});
另一个解决方案是在
uploadImageHandler
元素的 onload
事件中执行 img
。根据您的需求,您可以在这两种解决方案之间进行选择。 onload
解决方案与我解释的解决方案没有太大不同。我无法共享我的代码的所有部分,但我认为您可以使用我共享的部分代码和我解释的内容来实现上传图像功能。我希望它对你有用。