vue生成二维码 / base64图片实现点击复制

最近有个小项目,填写信息生成二维码,再发给人家。发送时需要复制名字 + 二维码图片到微信发送,之前每次是将内容信息复制到草料二维码生成,再复制该用户的名字,粘贴,发送, 再复制图片,粘贴,发送......有时候一次做十几个,重复机械的动作经常要重复十来次,非常麻烦。于是想着优化一下,由前端自己生成二维码,再做一个点击一键复制,甚至不需要点击,填写完毕提交自动复制......将偷懒做到极致。

生成二维码使用的是 qrcodejs2  组件

安装

npm i qrcodejs2

在页面中引入:

import QRCode from 'qrcodejs2';

二维码弹窗:

    <el-dialog :visible.sync="qrCodeVisible" width="600px" style="background-color: black;">
      <p class="pointer" @click="copy(certName)" style="font-size: 25px;font-weight: bold;">{
   
   { certName }}</p>
      <br />
      <div class="pointer" @click="copyQrCode()" id="qrCode" align="center"></div>
    </el-dialog>

其中id为"qrCode"的div,就是用来装二维码的地方。

pointer的class是为了实现鼠标放上去显示手指的效果。

  /*光标呈现为指示链接的指针(一只手)*/
.pointer:hover {
  cursor: pointer;
}

实现文字点击复制:

    copy(item) {
      const input = document.createElement('input');
      document.body.appendChild(input);
      input.setAttribute('value', item);
      input.select();
      if (document.execCommand('copy')) {
        document.execCommand('copy');
        this.$message.closeAll();
        this.$message({
          showClose: true,
          message: '已复制',
          type: 'success'
        });
      }
      document.body.removeChild(input);
    },

实现生成二维码:

    //生成二维码
    generateQrCode(md5Code) {
      //这里的  'qrCode'  即前面 div 的 id 需要对应
      let container = document.getElementById('qrCode');
      //清空之前的二维码 如果不清空,再次执行本方法,就会有两张图片
      if (container.innerHTML) {
        container.innerHTML = '';
      }
      var qrcode = new QRCode(container, {
        text: this.urlPrefix + md5Code, //这里就是二维码扫描后展示的内容了
        width: 500,
        height: 500,
        colorDark: 'black ',
        colorLight: 'white',
        correctLevel: QRCode.CorrectLevel.L //二维码的纠错等级,等级越高,二维码呈现越复杂,同时被遮挡的多,也能扫出来
      });
    },

调用二维码生成的方法:

    //打开展示二维码的弹窗
    openQrCode(data) {
      this.qrCodeVisible = true;
      this.certName = data.name;
      //这里setTimeOut是延迟执行,作用是等待dom节点挂载,如果不加的话 会报下面的错
      setTimeout(() => {
        this.generateQrCode(data.md5Code);
      }, 100);  //100代表 100毫秒 即0.1s
    },

如果不延迟执行,报错如下:

点击按钮调用方法,打开二维码弹窗:

 看看效果:

 接下来实现点击复制图片:

由于我这里的二维码图片是由前端本地生成,且为base64格式:

 可以看到 src并非url,而是base64字符串。

在看了一众csdn资料后,发现不如直接将base64转为Blob类型,直接写入就好了。

base64转Blob:

    base64ToBlob(dataurl) {
      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 Blob([u8arr], { type: mime });
    },

点击复制二维码:

    //点击复制二维码
    copyQrCode() {
      let container = document.getElementById('qrCode').childNodes[1];
      let myBlob = this.base64ToBlob(container.getAttribute('src'));
      navigator.clipboard.write([new window.ClipboardItem({ [myBlob.type]: myBlob })]);
    }

注意这里获取的dom是qrCode的第二个子节点

document.getElementById('qrCode').childNodes[1]

因为我的图片是由qrcodejs2  生成,实际的dom结构是:

如果直接使用qrCode的dom,点击复制出来的宽度会与原本的不同,并且有白边。

原本图片大小:500 x 500

使用qrCode的dom复制出来的:700 x 625 

不仅大小变大了,缩放后发现左右两边还多了30的白边,反复检查,发现就是dom选择错的问题,直接选择img复制,大小就没问题,并且没有白边。

注意!!!

 navigator.clipboard.write

该方法的确只能在本地localhost 、127.0.0.1 或者 https 协议下使用,否则navigator没有clipboard方法。

由于新版浏览器的安全策略,clipboard只有在安全域名下才可以访问,http域名下会显示undefined,但使用https开头的域名,或localhost,就可以访问navigator.clipboard

粘贴试试:

 

 效果符合预期。

如果图片url是网络上的,是以url形式展示的,建议参考:



​​​​​vue实现点击按钮复制图片(类似浏览器右键复制)_LingSnow1019的博客-CSDN博客_vue实现点击按钮复制图片

其实我的需求没有完全实现,最初想的是点击直接复制【文字+图片】,现在还是得分别复制,在我尝试了一下直接同时复制网页上的图片+文字到QQ聊天窗 或 编辑器、word文档中时,粘贴后发现效果都没问题,都是支持的,而唯独复制到电脑端的微信聊天窗口中,粘贴后文字显示,但图片会不显示,变成了一个空格,既然电脑微信已经不支持,那就不是前端这边能解决的问题了。

勉强将就用用,至少不用再去草料二维码生成一次了。

猜你喜欢

转载自blog.csdn.net/qq_16382227/article/details/125317902