React-Quill中的图片上传及显示

前两篇文章介绍了在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
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页