React-Quill 自定义上传图片按钮



  • 为什么要图片上传需要自定义呢?
    因为默认的上传方式是直接把图片转换成Base64编码发到后台,在后面获取图片的时候,服务器会把冗长的图片的Base64编码发送过来,而不是一个图片Url,因此会使服务器负担加重。那么我们需要在后台返回夹杂图片的文本的时候,不需要后台把图片的Base64编码发送过来,只需要把图片url链接发送过来。这样可以减轻发送文本的负担。


    一、改动方法:

    点击图片按钮,选择图片,然后网页会把本地地址图片转为Base64编码发到后台,然后获取后台的图片Url。前台网页会将Url所代表的页面显示在文本框中。在上交时会把<img>标签上传。

    二、改动方面:

    1. 全局变量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'
      ]
    }
    
    1. 在组件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}
    />
    
    1. 在class组件构造函数constructor中定义一个this.Editor
    constructor(){
    ...
    //实现深拷贝,防止其他模块的Editor受影响
    this.Editor = JSON.parse(JSON.stringify(Editor))
    this.Editor.modules.toolbar.handlers.image = this.getLocalImage   
    //与本组件的getLocalImage方法绑定,所以不能在全局的Editor上写绑定函数
    ...
    }
    
    1. getLocalImage()函数
    getLocalImage() {
        var input = document.getElementById("uploadInput")   //获取input标签
        input.click()                      //调用获取本地图片
        input['data-ref'] = this           //在input的私有数据中存放this,注意这个this指代的是React-Quill富文本编辑器,并且是点击的那个
        //'data-*'是html5所有,以前的html版本不适用
      }
    
    1. 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;
        }
      }
    

    这样大概就可以完成图片上传的功能了。

    参考资料:react-quill 富文本编辑器中自定义图片插入(图片上传)



  • 这个代码还有形形色色的bug,欢迎大家前来指正。


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待