最近博客中用到了这个富文本组件,发现这组件的图片无法支持 截图黏贴以及上传图片是一长串base64字符串,非常不方便,所以通过文档,自定义一个一下上传方式,效果如图
其中,上传图片是调用组件自带的hook,
复制图片,则通过自定义paste事件,获取剪切板上的数据。然后上传到后台,获取到url然后在插入到组件的markdown中
首先看组件的代码
其中addImageBlobHook是自定义上传图片的插件
const addImageBlobHook = async ( blob: Blob | File, callback: (url: string, altText?: string) => void ) => { let url = await uploadImg(blob); //alttext不传则为输入的描述信息 if (url) callback(url); };
然后是自定义富文本的paste事件
const editorIntance = ref.current.getInstance(); editorIntance.addHook('paste', (info: { data: ClipboardEvent; }) => { const clipboardData = info.data.clipboardData; if (clipboardData.items) { const items = clipboardData.items; console.log(items); const len = items.length; let blob = null; info.data.preventDefault(); // 在items里找粘贴的image,据上面分析,需要循环 for (let i = 0; i < len; i++) { if (items[i].type.includes('image')) { blob = items[i].getAsFile(); } else items[i].getAsString((str) => { if (str.startsWith("") && str.includes("
如果剪切板的类型是图片,便提取出blob
如果直接复制图片不是截图,那么会是html的字符串,那如果是img元素,那就提取出图片,在插入到markdown内
完整的代码如下
const CommonEdiror = React.forwardRef((props: IEditorProps, ref: React.MutableRefObject) => { const addImgToMd = (data) => { console.log('data: ', data); const editorIntance = ref.current.getInstance(); const editor = editorIntance.getCodeMirror(); editorIntance.insertText(editor.getValue() + `![img](${data})`); }; const addImageBlobHook = async ( blob: Blob | File, callback: (url: string, altText?: string) => void ) => { let url = await uploadImg(blob); //alttext不传则为输入的描述信息 if (url) callback(url); }; const uploadImg = async (blob: Blob, isInsert = false) => { const formdata = new FormData(); formdata.append("files", blob); let res = await Post(UploadImgUrl, formdata); if (res.code === 200) { let url = "https://www.dodream.wang" + res.data.url; if (isInsert) addImgToMd(url); return url; } return null; }; useEffect(() => { const editorIntance = ref.current.getInstance(); editorIntance.addHook('paste', (info: { data: ClipboardEvent; }) => { const clipboardData = info.data.clipboardData; if (clipboardData.items) { const items = clipboardData.items; console.log(items); const len = items.length; let blob = null; info.data.preventDefault(); // 在items里找粘贴的image,据上面分析,需要循环 for (let i = 0; i < len; i++) { if (items[i].type.includes('image')) { blob = items[i].getAsFile(); } else items[i].getAsString((str) => { if (str.startsWith("") && str.includes(" );});