React-Quill 自定义上传图片按钮
-
为什么要图片上传需要自定义呢?
因为默认的上传方式是直接把图片转换成Base64编码发到后台,在后面获取图片的时候,服务器会把冗长的图片的Base64编码发送过来,而不是一个图片Url,因此会使服务器负担加重。那么我们需要在后台返回夹杂图片的文本的时候,不需要后台把图片的Base64编码发送过来,只需要把图片url链接发送过来。这样可以减轻发送文本的负担。
一、改动方法:
点击图片按钮,选择图片,然后网页会把本地地址图片转为Base64编码发到后台,然后获取后台的图片Url。前台网页会将Url所代表的页面显示在文本框中。在上交时会把<img>标签上传。
二、改动方面:
- 全局变量
Editor
const Editor = { modules: { toolbar: { container: [ //层级有所改变 [{ 'font': [] }], [{ size: [] }], ['bold', 'italic', 'underline', 'strike'], [{ 'indent': '-1' }, { 'indent': '+1' }], ['link', 'image'], ], handlers: { 'image': ''//添加了handlers对按钮重新申明调用的函数方法 } }, //imageDrop: true, //这个是用来剪贴图片的,需要下载安装插件 clipboard: { // toggle to add extra line breaks when pasting HTML: matchVisual: false, } }, formats: [ 'font', 'size', 'bold', 'italic', 'underline', 'strike', 'indent', 'link', 'image' ] }
- 在组件
render()
,return
的html标签代码中,添加下列<input>
标签(只需要一个就可以了),用来获取本地图片:
注意:要隐藏<input>
标签,并且悬浮。
<input id="uploadInput" type='file' accept='image/*' style={{width:"100px",border:"none",visibility:"hidden"}} onChange={this.uploadImage.bind(this)} />
使用富文本编辑器的html代码:
<ReactQuill theme='snow' modules={this.Editor.modules} formats={this.Editor.formats} />
- 在class组件构造函数
constructor
中定义一个this.Editor
constructor(){ ... //实现深拷贝,防止其他模块的Editor受影响 this.Editor = JSON.parse(JSON.stringify(Editor)) this.Editor.modules.toolbar.handlers.image = this.getLocalImage //与本组件的getLocalImage方法绑定,所以不能在全局的Editor上写绑定函数 ... }
getLocalImage()
函数
getLocalImage() { var input = document.getElementById("uploadInput") //获取input标签 input.click() //调用获取本地图片 input['data-ref'] = this //在input的私有数据中存放this,注意这个this指代的是React-Quill富文本编辑器,并且是点击的那个 //'data-*'是html5所有,以前的html版本不适用 }
uploadImage()
函数
//获取图片成功后,会调用onChange的uploadImage函数 //可以封装成全局函数 uploadImage(e) { const file = e.target.files[0]; let url = '' let input = document.getElementById("uploadInput") console.log("file", file) console.log(input) if (!file) { return; } // 匹配类型为image/开头的字符串 if (file.type === "image/png" || file.type === "image/jpeg") { //图片上传 var reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function (e) { // 读取到的图片base64 数据编码 将此编码字符串传给后台即可 var imgcode = e.target.result; console.log(imgcode) } //图片上传请求,需要返回url,可以封装成全局函数 //let url = "https://www.baidu.com/img/baidu_jgylogo3.gif" //测试图片url //下面的插入图片可以封装成全局函数 let quill = input['data-ref'].quill; //获取到编辑器本身 const cursorPosition = quill.getSelection().index; //获取当前光标位置 quill.insertEmbed(cursorPosition, "image", url, Quill.sources.USER);//插入图片 quill.setSelection(cursorPosition + 1); //光标位置加1 input.value = '' //清空input,防止上传同一张图片不发生onChange函数 } else { message.error("图片上传只支持JPG/PNG格式,请重新上传!"); return; } if (file.size / 1024 / 1024 > 5) { message.error("图片上传大小不要超过5MB,请重新上传!"); return; } }
这样大概就可以完成图片上传的功能了。
- 全局变量
-
这个代码还有形形色色的bug,欢迎大家前来指正。