[天坑]之qrcode二维码在app内置浏览器中无法显示问题

发布时间 2023-06-11 02:26:03作者: 艾码的日常生活

记录一下最近的工作难点,之一...

首先本项目使用的是qrcode-generator,市面上生成二维码的第三方库有很多qrcode.vue、qrcode、QRious等等

<div id="qrcode"></div>
import QRCode from "qrcode-generator";
  data() {
    return {
      tenant: "turnchartenantkey",
      url: "",
      id: "",
      storeObj: {},
    };
  },
  created() {
    this.generateQRCode();
    // this.drawQrc();
  },
  methods: {
            generateQRCode() {
            //省略*****多判断及请求
                // 获取容器元素;
                const container = document.getElementById("qrcode");
                // 创建二维码生成器实例
                const qr = QRCode(0, "L");
                // 设置二维码内容
                this.url = `your url`;
                console.log(this.url, "url");
                qr.addData(this.url);
                qr.make();
                // 渲染二维码到容器元素中
                container.innerHTML = qr.createSvgTag({
                  scalable: true,
                });     
}           
//css
  #qrcode {
    width: 300px;
    height: 300px;
    margin: 0 auto;
    padding: 25px;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
  }

看着挺正常的,就是普通的qrcode生成二维码,暗藏玄机

是的,app内置浏览器中无法显示二维码,尝试过各种方法,排除了各种可能导致错误的原因,最后确定在手机可能对svg的编译存在一些误差,要优化代码并使二维码在应用程序的嵌入式浏览器中正常显示,首先需要将其转换为数据 URL 并使用img标签来显示二维码,而不是将二维码呈现为 SVG 直接插入 DOM。这种方法更兼容不同的浏览器和嵌入式 Web 视图。

模板部分中的<div id="qrcode"></div>替换为。

<img id="qrcode" :src="qrcodeUrl" alt="QRcode">

 

添加qrcodeUrldata部分并更新generateQRCode设置二维码数据 URL 的方法,qrcodeUrl而不是直接修改 DOM。

下面是更改后的代码

<template>
  <div>
    <div class="qr-card">
      <div class="qrcode-container">
        <div v-if="loading" class="loading-spinner"></div>
        <img v-else id="qrcode" :src="qrcodeUrl" alt="QR Code" />
      </div>
    </div>
  </div>
</template>

<script>
import QRCode from "qrcode-generator";

export default {
  name: "QRcode",
  data() {
    return {
      qrcodeUrl: "", 
      loading: true, 
    };
  },
  created() {
    this.generateQRCode();
  },
  methods: {
    generateQRCode() {
                const qr = QRCode(0, "L");
                this.url = `your url`;
                qr.addData(this.url);
                qr.make();
                const svgTag = qr.createSvgTag({ scalable: true });

                // 将 SVG 转换为数据 URL
                const svgBlob = new Blob([svgTag], { type: "image/svg+xml" });
                const svgUrl = URL.createObjectURL(svgBlob);
                this.qrcodeUrl = svgUrl;

                // 不再需要时释放对象 URL
                this.$once("hook:beforeDestroy", () => {
                  URL.revokeObjectURL(svgUrl);
                });

                this.loading = false; 
    },
  },
};
</script>

<style lang="less" scoped>
* {
  box-sizing: border-box;
}

  .qrcode-container {
    width: 300px;
    height: 300px;
    margin: 0 auto;
    padding: 25px;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .loading-spinner {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    border: 3px solid #ccc;
    border-top-color: #333;
    animation: spin 1s linear infinite;
  }

  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }
}
</style>

在此更新的代码中,SVG QR 代码使用转换为数据 URL"URL.createObjectURL"并分配给"qrcodeUrl". 该"URL.revokeObjectURL"方法在组件销毁之前调用以释放对象 URL。<img>然后使用带有qrcodeUrlas属性的标签显示 QR 码src,并且添加加载中loading,loading属性设置为true,表示加载状态处于活动状态。二维码生成显示成功后,loading设置为false,显示二维码时隐藏加载框。