Vue中调用qrcodejs2生成二维码,并将canvas转为图片格式使得移动端使用时可长按识别。(含批量生成二维码时遇到的坑,封装组件

业务需求,需要使用JS将url链接转为二维码图片。查到可以使用qrcodejs2传入内容、大小获得一个画布上的二维码。但是canvas标签在移动端上无法使用长按识别的功能,所以还需要把canvas对象转换为图片img标签。

网上找到的相关资料大多是通过html2canvas来将二维码转为图片的,但通过这种方法,总有一些奇奇怪怪的问题,比如有时候明明转成了base64,但是页面不显示。后来还是选择直接转为image,使用起来也更灵活。

首先安装qrcodejs2:

npm install qrcodejs2 --save 

可以参考使用文档:https://www.npmjs.com/package/qrcodejs2
需要注意的一些踩坑点:

  1. qrcode()生成方法,不能写在created()中调用,因为页面必须先渲染后再生成二维码。初始化时放在mounted钩子中,并延迟300
  2. 批量生成二维码时,虽然传入了不同的内容值,出现了页面二维码显示重复,后台输出其实是生成了不同二维码的。原因是生成的二维码挂在了同一个div上,所以批量生成的时候需要传入id值!!!!
  3. 如果传入的宽高值小,生成的二维码可能会出现不清晰的情况,最好的解决办法的生成二维码时放大,再使用css缩小。比如说想要一个80*80的二维码图片,可以传入height:400,width:400,再在标签外部使用css设置宽高值。
    解决方法参考了:解决生成二维码长字符串显示模糊问题
  4. 不要在二维码的div上设置宽高!不要在二维码的div上设置宽高!不要在二维码的div上设置宽高!否则会和第三点使用css设置宽高值冲突哈哈哈。

这里直接放上封装好的子组件了,qrcodeimg.js:

<template>
  <div>
    <img v-if="imgData != ''" :src="imgData" />
    <div :id="qrid" class="qrcode" v-show="imgData == ''"></div>
  </div>
</template>
<script>
import QRCode from "qrcodejs2" // 引入qrcode
export default {
  name: "QrCodeImg",
  props: ["qrid", "qrContent", "qrWidth", "qrHeight"],
  data() {
    return {
      imgData: "",
    }
  },
  watch: {
  //监听二维码内容值的变化,重新生成二维码
    qrContent: function (val) {
      this.qrcode()
    },
  },
  created() {},
  mounted() {
    setTimeout(() => {
      this.qrcode()
    }, 300)
  },
  methods: {
    qrcode() {
      this.$nextTick(() => {
        document.getElementById(this.qrid).innerHTML = "" //否则每生成一次,上次的还存在,都会多一个二维码
        //要先生成div再生成二维码,否则Cannot read properties of undefined (reading 'appendChild')
        new QRCode(this.qrid, {
          text: this.qrContent,
          //text为转换为二维码的文本,可以是所有东西:图片、文本、电话、链接等等
          width: this.qrWidth, //生成二维码的宽度
          height: this.qrHeight, //生成二维码的高度
          colorDark: "#333333", // 二维码颜色
          colorLight: "#F8F8FF", //二维码背景颜色
        })
      })
      var canvasobj = document.getElementsByTagName("canvas")[0]
      // 将转换后的img标签插入到html中
      var img = this.CanvasToImage(canvasobj)
      this.imgData = img.src
    },
    CanvasToImage(canvas) {
      //从canvas中提取图片image,新建image对象
      var image = new Image()
      // canvas.toDataURL 返回Base64编码的URL
      image.src = canvas.toDataURL("image/jpg")
      return image
    },
  },
}
</script>
<style lang="scss" >
</style>

父组件调用qrcodeimg.js如下:

<template>
  <div class="container" id="app">
    <div id="qrcodeArea">
    //生成单个二维码时可以固定id值
      <QrCodeImg
         :qrid="'currentQr'"
         :qrContent="qrContent"
         :qrHeight="qrHeight"
         :qrWidth="qrWidth"
      />
    </div>
    //批量生成二维码时需要动态传入id!!
    <el-table border :data="tableList" class="tableBox">
    	<el-table-column label="二维码" width="100px">
              <template slot-scope="scope">
	              <div id="qrcodeArea">
	                <QrCodeImg
	                  @dblclick.native="qrcodedoubleClick(scope.$index)"
	                  :qrid="scope.row.id"
	                  :qrContent="scope.row.query_prod_entry"
	                  :qrHeight="qrHeight"
	                  :qrWidth="qrWidth"
	                />
	   			  </div>
              </template>
         </el-table-column>
     </el-table>
   </div>
</template>

<script>
import QrCodeImg from "../../components/QrCodeImg/QrCodeImg.vue"
export default {
  components: {
    QrCodeImg,
  },
  data() {
    return {
      qrWidth: 400,
      qrHeight: 400,
      qrContent: "https://www.baidu.com/",
    }
  },
  computed: {},
  watch: {},
  mounted() {},
  methods: {},
  created() {},
}
</script>
<style lang="scss">
#qrcodeArea img {
  height: 80px;
  width: 80px;
}
</style>
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值