vue-quill-editor粘贴截图base64改上传

2,309 阅读2分钟

vue-quill-editor是一个基于 Quill、适用于 Vue 的富文本编辑器,支持服务端渲染和单页应用,是vue的quill第三方库。

在开发过程中发现编辑时截图粘贴默认使用base64编码展示,但是如果是很大的图片,base64编码过长会导致编辑页面渲染缓慢,同时上传文本过长,给服务器造成压力🍐。网上没有搜到合适的解决方案,这里贴出我自己的处理方法,欢迎指正。

下面说一下优化方案:

调整粘贴截图的方式从base64编码改为文件上传,并使用上传后的图片路径展示。

详细步骤如下:

1、捕获粘贴截图事件

data() {
    editorOption: {
        modules: {
            clipboard: { // 剪切板事件
                matchers: [
                    ['img', this.handlePasteImg] // 匹配图片剪切板
                ],
            }
         }
    }
}

2、处理base64编码为图片文件上传并展示

2.1 获取到截图的base64编码

2.2 转化base64编码为图片(File格式)

2.3 将图片文件上传到文件服务器,并返回上传的文件路径进行展示

  methods: {
    handlePasteImg: function(node, delta){
      // 调整为上传,给回路径
      let _self = this;
      let base64code = delta && delta.ops 
                       && delta.ops[0] && delta.ops[0]['insert'] 
                       && delta.ops[0]['insert']['image']; // 2.1

      if(base64code && base64code.indexOf("https://")!==0){ // 已经上传的不处理,可自定义判断逻辑
        let file = _self.dataURLtoFile(base64code, 'paste.png'); // 2.2
        var formData = new FormData();
        formData.append("upfile", file);
        _self.gUpload(formData, function(res) {
          // 2、处理插入
          
          // 获取富文本对象
          let quill = _self.$refs['myQuillEditor'].quill
          // 获取编辑器光标位置
          let length = quill.selection.savedRange.index;
          // 插入图片至光标位置,imgUrl为图片地址
          quill.insertEmbed(length, 'image', res.url);
          // 移动光标至图片后面
          quill.setSelection(length + 1);
        });
        // 1、等待请求返回做不到同步,先返回空,在请求回调中再添加(这里监听函数接收职能接收同步的数据,特殊处理)
        delta.ops = [];
        return delta;
      }else{
        return delta;
      }
    },
    // 图片的base64编码转为图片文件
    dataURLtoFile: function(dataurl, name) {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while(n--){
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], name, {type:mime});
    },
    gUpload: function(params, callBack) {
        let _self = this;
        let url = "XXXXXX"; // 文件上传接口
        _self.axios.post(url, params, {
            withCredentials: false,
        }).then(function(response) {
            let data = response.data
            callBack(data); // 回调
        }).catch(function(response) {
            // 捕获异常
        });
    },
 }