前端自动生成二维码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格式的图片
      };
    },
}
相关推荐
Allen Bright19 分钟前
【HTML-2】HTML 标题标签:构建网页结构的基础
前端·html
Dragon Wu30 分钟前
Taro Error: chunk common [mini-css-extract-plugin]
前端·小程序·前端框架·react·taro
Dragon Wu34 分钟前
Taro 安全区域
前端·小程序·前端框架·taro
yuren_xia39 分钟前
Vue3 组件之间传值
前端·javascript·vue.js
爱吃鱼的锅包肉41 分钟前
记录一下flutter项目自己封窗的弹窗
前端·javascript·flutter
Frank学习路上41 分钟前
【Flutter】创建BMI计算器应用并添加依赖和打包
前端·javascript·flutter
黄暄1 小时前
Spring Boot 登录实现:JWT 与 Session 全面对比与实战讲解
javascript·网络·spring boot·后端
风清云淡_A1 小时前
【react18】在styled-components中引入图片报错
前端·reactjs
JiaLin_Denny1 小时前
react中运行 npm run dev 报错,提示vite.config.js出现错误 @esbuild/win32-x64
javascript·react.js·npm·esbuild·config.js·run dev
GUIQU.2 小时前
【Node.js】Web开发框架
前端·node.js