使用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

参考博客:Vue使用QrcodeVue生成二维码并下载

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使用的话会提示版本问题。

Logo

前往低代码交流专区

更多推荐