前端自动生成二维码qrcodejs2

插播一条

走过路过,帮忙投个票吧,万分感谢!掘金2023年度人气创作者打榜中,快来帮我打榜吧~ activity.juejin.cn/rank/2023/w...

前言

业务中经常会有这样的使用场景,后端返回一串文本,需要前端根据这段文本生成相应的二维码.

需求分析:

  1. 后端返回文本, 前端根据该文本自动生成二维码,二维码可以手动刷新.
  2. 手动刷新就是更新时间戳+文本来重新生成最新的
  3. 生成二维码的规则: 当前时间戳/后端返回的固定文本

实现

使用qrcodejs2插件来生成二维码.

安装

sh 复制代码
npm install qrcodejs2 --save

组件封装

html 复制代码
<template>
  <div class="my-qrcode">
    <div :style="`height: ${height}px;`" :id="domId" :ref="domId"></div>
    <p class="qrcode-desc">
      <span @click="refresh">刷新</span>
    </p>
  </div>
</template>
js 复制代码
import QRCode from "qrcodejs2";
export default {
  name: "Qrcode",
  props: {
    domId: {
      type: String,
      default: "qrcode",
    },
    width: {
      type: Number,
      default: 148,
    },
    height: {
      type: Number,
      default: 148,
    },
    text: {
      type: String,
      default: "",
    },
    colorLight: {
      type: String,
      default: "#ffffff",
    },
    colorDark: {
      type: String,
      default: "#000000",
    },
  },
  data() {
    return {
      qrcode: null,
      codeText: "",
    };
  },
  mounted() {
    this.refresh();
  },
  watch: {
    text(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.refresh();
      }
    },
  },
  methods: {
    createQrcode() {
      if (this.qrcode) {
        this.qrcode.clear(); // 清除之前的二维码
        this.qrcode.makeCode(this.codeText); // 重新绘制二维码
      } else {
        this.qrcode = new QRCode(this.$refs[this.domId], {
          width: this.width,
          height: this.height,
          colorDark: this.colorDark,
          colorLight: this.colorLight,
          correctLevel: QRCode.CorrectLevel.H,
          text: this.codeText,
        });
      }
    },
    refresh() {
      const date = new Date();
      this.codeText = `${date.getTime()}/${this.text}`;
      
      this.$nextTick(() => {
        this.createQrcode();
      });
    },
  },
};
less 复制代码
<style lang="less" scoped>
.my-qrcode {
  display: flex;
  flex-direction: column;
  align-items: center;

  .qrcode-desc {
    text-align: center;

    span {
      font-size: 14px;
      font-weight: 400;
      color: #3e6dff;
    }
  }
}
</style>

使用

js 复制代码
import QrCode from "@/components/qrcode";
export default {
  components: {
    QrCode,
  },
  data() {
      return {
          qrcodeText: ''
      }
  }
}
html 复制代码
<QrCode domId="qrcodePreview" :text="qrcodeText" />

预览

遇到的问题

问题:在部分机型上,绘制二维码失败?

分析:qrcode自带生成的base64图片是png格式,在部分机型上png图片无法显示。

解决:通过canvas重新生成jpg格式的图片后,再替换已有的png图片就可以了。(在出问题的机型上再次测试,问题已解决)

js 复制代码
methods: {
    createQrcode() {
       .....
        
       // 解决部分真机上无法显示二维码情况(png图片无法绘制到canvas中)
      if(this.qrcode) {
        this.resolveQrcode();
      }
    
    },
    
    // 重新绘制二维码图片
    resolveQrcode() {
      let dom = document.querySelector(`#${this.domId}`);
      let qrcanvas = document.querySelector(`#${this.domId} > canvas`);// 已生成的canvas
      let qrcanvasImg = document.querySelector(`#${this.domId} > img`); // 已生成的img
      let qrBase64 = qrcanvas.toDataURL("image/jpeg"); // 转成JPG

      let qrImg = new Image();
      qrImg.crossOrigin = "anonymous";
      qrImg.src = qrBase64;

      qrImg.onload = () => {
        qrcanvas.style.display = "none"; // canvas隐藏(fixbug: oppo手机未自动隐藏,显示两个二维码)

        qrcanvasImg && dom?.removeChild(qrcanvasImg); // 移除已生成的base64png图片
        dom && dom.appendChild(qrImg); // 添加已转换成JPG格式的图片
      };
    },
}
相关推荐
Csvn24 分钟前
Vue 3 defineModel 翻车实录:多个 v-model 绑定到底怎么写?
前端·vue.js
甲维斯28 分钟前
坦克大战测试全翻车了!豆包,DeepSeek,Qwen,GPT,Claude
前端·人工智能·游戏开发
乘风gg1 小时前
还在养虾吗?虾王已诞生:微信龙虾 ClawBot
前端·ai编程·claude
小小小小宇2 小时前
LLM 长期记忆构建
前端
lichenyang4532 小时前
从 Express 老项目到 NestJS + Docker:一次车辆管理系统的渐进式重构
前端
竹林8183 小时前
用 wagmi v2 + viem 监听链上事件,我踩了三天坑终于搞懂了实时日志与历史补全
javascript
Momo__3 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
只一3 小时前
😭从回调地狱到 async/await:一文打通 Ajax 与 JS 异步编程
javascript
程序员小富3 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇3 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端