vue生成二维码 / base64图片实现点击复制
vue生成二维码base64图片实现点击复制qrcodejs2html2canvas生成图片图片有白边
最近有个小项目,填写信息生成二维码,再发给人家。发送时需要复制名字 + 二维码图片到微信发送,之前每次是将内容信息复制到草料二维码生成,再复制该用户的名字,粘贴,发送, 再复制图片,粘贴,发送......有时候一次做十几个,重复机械的动作经常要重复十来次,非常麻烦。于是想着优化一下,由前端自己生成二维码,再做一个点击一键复制,甚至不需要点击,填写完毕提交自动复制......将偷懒做到极致。
生成二维码使用的是 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文档中时,粘贴后发现效果都没问题,都是支持的,而唯独复制到电脑端的微信聊天窗口中,粘贴后文字显示,但图片会不显示,变成了一个空格,既然电脑微信已经不支持,那就不是前端这边能解决的问题了。
勉强将就用用,至少不用再去草料二维码生成一次了。
更多推荐
所有评论(0)