【vue2,3使用QRCode进行二维码的生成和下载】
vue2,3使用QRCode进行二维码的生成和下载
使用QRCode生成二维码vue2和vue3都已实现。
在使用dialog弹窗中生成二维码会出现DOM延迟问题,本文也展示了DOM延迟的解决方法,可做参考。
1 vue2使用Qrcode
1.1 安装Qrcode
npm install qrcodejs2
1.2 引入Qrcode
import QRCode from 'qrcodejs2';
1.3 生成二维码
<div style="justify-content: center;align-items: center;display: flex;" ref="qrcode"></div>
......
<script>
new QRCode(this.$refs.qrcode, {
text: this.item.title, // 替换为你要生成二维码的内容
width: 200,
height: 200,
});
</script>
1.4 因弹窗显示二维码出现的dom延迟问题解决方式
<template>
<div class="notice">
<van-button type="primary" @click="onItemClick">打开二维码</van-button>
<van-dialog v-model:show="show" :title="item.title" @confirm="changeStatus"
showCancelButton="true" cancelButtonText="下载" cancelButtonColor="#ee0a24" @cancel="downloadCode">
<div style="justify-content: center;align-items: center;display: flex;" ref="qrcode"></div>
</van-dialog>
</div>
</template>
<script>
import QRCode from 'qrcodejs2';
export default {
data() {
return {
show: false,
qrcode: null,
}
},
methods: {
onItemClick() {
this.show = true;
this.$nextTick(() => {
//判断该二维码是否已经存在,存在则无需再次生成
if (!this.qrcode) {
// 生成二维码
this.qrcode = new QRCode(this.$refs.qrcode, {
text: this.item.title, // 替换为你要生成二维码的内容
width: 200,
height: 200,
});
}
});
},
changeStatus() {
this.$toast('点击确认事件');
},
downloadCode() {
//获取二维码中格式为imag的元素
const nodeList = Array.prototype.slice.call(this.qrcode._el.children)
const img = nodeList.find((item) => item.nodeName.toUpperCase() === 'IMG') // 选出图片类型
// 构建画布
let canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0);
// 构造url
let url = canvas.toDataURL('image/png');
const a = document.createElement("a");
a.href = url;
a.download = `二维码.png`;
// 触发a链接点击事件,浏览器开始下载文件
a.click();
},
},
}
</script>
1.5 为什么使用$nextTick:
- Vue在观察到数据变化时,并不是直接更新DOM,而是开启一个队列,并且缓存同一轮事件循环中的所有数据改变。在缓冲时会除去重复的操作,等到下一轮事件循环时,才开始更新。
- $nextTick的作用:就是用来告知DOM什么时候更新完,当DOM更新完毕后,nextTick方法里面的回调就会执行。
几乎所有更新数据后操作dom的操作,都需要用到异步更新队列(即使用$nextTick)
使用 $nextTick解决了DOM延迟问题,有想法的同学可以看一下不使用 $nextTick的效果。
2.vue3使用Qrcode
2.1 安装Qrcode
npm install --save qrcode.vue
2.2 代码展示
<template>
<div id="app">
<qrcode-vue style="margin-left: 50px" :value="qrCodeUrl" :size="500"></qrcode-vue>
</div>
</template>
<script lang="ts" name="xxx" setup>
import QrcodeVue from 'qrcode.vue'
//二维码链接
const qrCodeUrl = ref("www.baidu.com");
</script>
2.3 二维码下载
function download() {
//获取canvas标签
let canvas = document.getElementById('app').getElementsByTagName('canvas')
//创建a标签
let a = document.createElement('a')
//获取二维码的url并赋值为a.href
a.href = canvas[0].toDataURL('img/png')
//设置下载文件的名字
a.download = '二维码'
//点击事件,相当于下载
a.click()
//提示信息
this.$message.warn('下载中,请稍后...')
},
目前这种写法实测未存在dom延迟问题
可以看到这种方法会更简单,但是vue2使用的话会提示版本问题。