前两篇文章介绍了在Quill中使用贴图模块,这篇文章我们说下怎样把base64编码的图片保存到文件服务器,并且用新的地址替换原来的base64。
上文说道在Quill的onChange
函数中可以除了普通的DOM,还可以通过editor.getContents()
获取Delta类型的数据。他基本上和json差不多,我们可以对其进行处理,进行图片的处理。
Quill-Delta的文档:https://quilljs.com/docs/delta/
通过调试或者看官方文档,可以知道对于图片类型的数据,结构是:
{
ops: [{
// An image link
insert: {
image: 'https://quilljs.com/assets/images/icon.png'
},
}]
}
对于base64编码的图片,那上面的image的值对应的就是base64的一长串数据。
这样,我们就可以通过遍历,获取到所有的base64编码图片(注意要筛掉url地址的图),然后可以转换成Blob类型,传给后端保存在文件服务器。下面是转化格式的代码:
convertBase64UrlToBlob = (urlData) => {
//去掉url的头,并转换为byte
const bytes = window.atob(urlData.split(',')[1]);
//处理异常,将ascii码小于0的转换为大于0
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
ia.forEach((i, index) => {
ia[index] = bytes.charCodeAt(index);
});
return new Blob([ia], { type: urlData.split(',')[0].split(':')[1].split(';')[0] });
};
至于上传的方法有很多,这里就不详述了,我用的是reqwest
,然后我们拿到图片的url地址,依次替换Delta中的base64,这样我们拿到的Delta数据就没有那么大了,可以保存到数据库中了。注意要转成string,如JSON.stringify(Delta.ops)
。
这样是可以保存了,但我们要如何在前端中去展现输入的数据呢?我的办法是:
首先从后端拿到Delta的string,然后再次利用JSON.parse(Delta)
转回json格式。这样我们就可以对其进行操作了。如果不需要对数据进行特殊处理,可以直接转换成DOM结构然后直接渲染到网页中。
转Delta到DOM:https://github.com/nozer/quill-delta-to-html
// 引入quill-delta-to-html
const QuillDeltaToHtmlConverter = require('quill-delta-to-html');
// 转换Delta到html,更多功能请看上面链接中的介绍
const converter = new QuillDeltaToHtmlConverter(delta, {});
const html = converter.convert();
// 利用dangerouslySetInnerHTML渲染DOM,注意要对进行过滤转换,防止脚本攻击
<div dangerouslySetInnerHTML={{__html: `${this.escape(html)}`}}/>
这样我们就把Delta的数据显示到了网页中,如果我们想要对处理,假设对于图片想加一个点击放大查看的功能,就可以对Delta进行遍历,普通内容依照上面的方法显示,对于图片则用组件进行封装。
React图片查看组件:https://github.com/fritz-c/react-image-lightbox
功能和使用都很简单,代码如下:
import Lightbox from 'react-image-lightbox';
<div>
<img
src={item.insert.image}
width="300px"
style={{display: 'block'}}
alt={HAP.getMessage('图片加载中...', 'Image Loading...')}
onClick={() => this.onOpenLightboxChange()}
/>
{this.state.isOpen ?
<Lightbox
mainSrc={item.insert.image}
onCloseRequest={() => this.onOpenLightboxChange()}
imageTitle={'images'}
/> : ''}
</div>
通过onOpenLightboxChange
函数控制isOpen
来显示和隐藏lightbox
。效果如图:
到这里,使用Quill富文本编辑器对图片的一系列处理都说完了。
我还找到了Quill的表情模块,但还没去研究怎么在react中使用。
Quill-Emoji:https://github.com/contentco/quill-emoji