wangeditor粘贴文本+图片实现图片上传功能

editor.config.pasteTextHandle是配置粘贴文本内容处理,是一个函数,返回值就是文本框中粘贴的数据

如果单独粘贴一张图片不会执行次函数,会直接执行图片上传函数,只有粘贴文本或者文本与图片混合时才会执行此函数。

通过这个函数可以将粘贴的图片保存到自己的服务器或其他OSS,方式原图连接失效,造成图片不显示

流程

先判断粘贴的信息中是否存在图片连接,存在连接就执行函数,不存在就直接返回文本

存在连接就执行函数流程:

通过 editor.config.pasteTextHandle调用disposePasteImg处理粘贴的图片,得到图片路径,然后调用imgUrlSwitchBlob将图片路径转成图片对象,得到图片对象之后调用upPasteImg将图片进行上传并得到路径,最后以此返回

创建函数处理粘贴的图片

函数接受的参数是editor.config.pasteTextHandle函数的参数

在这个函数中将图片地址进行提取,将图片地址传递到将图片地址转成文件对象函数中,然后通过.then获取上传之后的图片地址,将原来的图片地址进行替换,判断图片地址是否全部转换完成,转换完成之后将处理好的粘贴文本返回

    // 处理粘贴的图片,传递的参数是粘贴来的数据
    disposePasteImg(pasteStr) {
      let _this = this;
      return new Promise(function (resolve) {
        // 用于计数图片数量
        let imgNum = 0;
        //匹配图片
        var imgReg = /|\/>)/gi;
        //匹配src属性
        // eslint-disable-next-line no-useless-escape
        var srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i;

        // 提取图片连接
        pasteStr.replace(imgReg, function (txt) {
          return txt.replace(srcReg, function (src) {
            var img_src = src.match(srcReg)[1];
            // console.log(img_src);
            //正则把?x-oss-process后面的都去掉
            img_src = img_src.replace(/\?.*/i, "");
            // 查找到一个图片地址就讲图片数量加1
            imgNum++;

            // 将图片转成图片文件对象并上传得到图片地址,传递的参数是图片地址
            _this.imgUrlSwitchBlob(img_src).then((res) => {
              // console.log("得到的地址res", res);

              /**
               * 得到图片地址进行替换并将替换之后的文本返回渲染
               */
              // 图片地址进行替换
              pasteStr = pasteStr.replace(img_src, res);
              // 替换之后将图片数量减1
              imgNum--;
              // 只有图片数量变成0的时候才会进行返回
              if (imgNum == 0) {
                // console.log("返回imgNum", imgNum,pasteStr)
                resolve(pasteStr);
              }
            });
          });
        });
      });
    },

将图片地址转成文件对象

在函数disposePasteImg函数中调用了本函数,参数是图片地址本函数是通过创建图片对象将图片地址转成图片对象(图片文本),在本函数中需要提前确定文件的名称,图片上传函数不会在接受图片地址,只会接受文件名称和文件对象

/**
     * @函数名称: 将图片地址转成文件对象
     * @返回值:图片地址
     * @描述: 接受的参数是图片的全地址路径,在函数中调用upPasteImg函数上传图片得到图片路径并返回
     * @其它: 使用Promise处理异步问题
     * @param {String} param 图片地址
     */
    imgUrlSwitchBlob(param) {

      let _this = this;
      return new Promise(function (resolve) {
        // 得到图片后缀
        let suffix = param.substring(param.lastIndexOf(".") + 1); //获取后缀
        // 设置图片名称及后缀
        const key =
          new Date().getTime() +
          Math.random().toString().substr(2, 5) +
          "." +
          suffix;
        // 创建图片对象
        let image = new Image();
        // 允许跨域
        image.setAttribute("crossOrigin", "anonymous");
        image.src = param;
        image.onload = () => {
          let canvas = document.createElement("canvas");
          canvas.width = image.width;
          canvas.height = image.height;
          let ctx = canvas.getContext("2d");
          ctx.drawImage(image, 0, 0, image.width, image.height);
          canvas.toBlob((blob) => {
            // console.log("blob", blob)
            // 得到的blob是一个图片对象,经图片对象进行上传得到图片地址.key是文件名称
            /**
             * @函数名称: 调用函数进行上传
             * @返回值: 得到的图片路径
             * @param {String} key 图片名称,包含后缀
             * @param {Object} blob 文件对象
             */
            _this.upPasteImg(key, blob).then((res) => {
              resolve(res);
            });
          });
        };
      });
    },

图片上传七牛云

得到对象和文件名称之后就可以直接上传到服务器或者其他OSS,我这里是上传到七牛云

上传文件需要调用后端接口获取token,获取到token之后配置信息实现上传。

最后将得到的图片地址依次返回

   /**
     * @函数名称: 上传粘贴的图片
     * @返回值: 上传得到的图片地址
     * @描述: 将文件上传到七牛云
     * @其它: 使用Promise处理异步问题
     * @param {String} key  文件名称
     * @param {Object} file  文件对象
     */
    upPasteImg(key, file) {
      let _this = this;
      // 更改成Promise函数
      return new Promise(function (resolve) {
        // 获取七牛云的token
        _this.Get(_this._URL.createdqiniu).then((res) => {
          _this.qiNiuToken = res;

          //配置信息
          var config = {
            useCdnDomain: true, //表示是否使用 cdn 加速域名,为布尔值,true 表示使用,默认为 false
            region: qiNiu.region.z1, //选择上传域名区域;当为 null 或 undefined 时,自动分析上传域名区域
          };

          //额外的信息
          var putExtra = {
            fname: "", //文件原文件名
            params: {}, //object,用来放置自定义变量
            mimeType: null, // null || array,用来限定上传文件类型,指定null时自动判断文件类型
          };

          // 创建七牛上传
          const observable = qiNiu.upload(
            file,
            key,
            _this.qiNiuToken,
            putExtra,
            config
          );

          // 文件上传过程
          var observer = {
            //  正在上传 接收上传进度信息
            next(res) {
              // 上传进度
              console.log("next-res", res, parseInt(res.total.percent));
            },
            // 接收上传错误信息
            error(err) {
              _this.$message.error("文件上传失败");
              console.log(err);
            },

            // 接收上传完成后的信息
            complete(res) {
              // console.log("图片地址complete-res", res);
              // 得到数据之后通过Promise的resolve返回,使用的时候。then就可以获取到
              resolve("http://updatafiles.ybrecord.cn/" + res.key);
            },
          };
          /* eslint-disable no-unused-vars */
          var subscription = observable.subscribe(observer); // 上传开始
        });
      });
    },

调用函数及判断

以上是粘贴文本与图片混合信息将图片保存到指定位置并替换连接的方法,在editor.config.pasteTextHandle进行调用,这时候直接返回一个空就可以了,上面的方法全部是Promise函数,得到结果的时候已经return结束了,因此不能直接返回

使用官方提供的追加方法将数据进行追加,返回来的res就是处理好的粘贴信息

 // 配置粘贴文本的内容处理
      editor.config.pasteTextHandle = function (pasteStr) {
        
        
          _this.disposePasteImg(pasteStr).then((res) => {
            //console.log("配置粘贴文本的内容处理res", res);
// 将内容追加上
            editor.txt.append(res);
            
          });
        }

        return 
      };

通过以上就完整的实现粘贴文本图片替换功能,但是出现一个问题

由于返回的是空,那么粘贴单纯的文本就不会执行了,在程序走到一个函数的时候就断了,无法继续执行并且还没有报错

因此需要先判断用户粘贴的信息中是否存在图片地址,存在图片地址就执行图片上传的逻辑,不存在就直接返回

直接在editor.config.pasteTextHandle中修改代码,在图片上传的过程中wangeditor是没有任何反应的,防止用户多次粘贴启用loading

 // 配置粘贴文本的内容处理
      editor.config.pasteTextHandle = function (pasteStr) {
        
        // 需要判断是否是纯文本,不是纯文本执行函数,是纯文本返回
        // 验证图片中是否包含img标签,具有得到true否则得到false
        var containsImage = pasteStr.search(/= 0;
        // 存在图片就执行
        if (containsImage) {
          // 打开loading
          _this.pasteTextFulfill = true;
          _this.disposePasteImg(pasteStr).then((res) => {
            // console.log("配置粘贴文本的内容处理res", res);

            // 将内容追加上
            editor.txt.append(res);

            // 关闭loading
            _this.pasteTextFulfill = false;
          });
        }

        return containsImage ? "" : pasteStr;
      };

最终实现纯文本直接显示,文本与图片混合会替换图片地址的功能

说明

  1. 在使用的函数中全部是Promise是为了解决异步的问题

  2. 实现以上功能参考了多篇文章,如有bug自行处理,在我的项目中是能够正常运行的

  3. 上传七牛云的时候需要先安装七牛云的依赖并导入

    文档地址:https://developer.qiniu.com/kodo/sdk/1283/javascript

    1.npm 安装
    
      npm install qiniu-js
    
    2.引入
    
      constqiniu =require('qiniu-js') // or // import*asqiniufrom'qiniu-js'
    
  4. 安装并引入wangeditor

    wangeditor文档地址:http://www.wangeditor.com/doc/

    1.npm 安装

    npm 安装 npm i wangeditor --save

    2.引入

    import E from "wangeditor";

  5. UI组件库使用的是elementUI

你可能感兴趣的:(wangeditor粘贴文本+图片实现图片上传功能)