微信小程序生成多张二维码以及支持async await

需求来了

最近项目需要在列表里生成微信二维码,之前用的是qrcode.js,但是只是用于生成一张图片。这次网上搜了下插件,很多也都用qrcode.js,我找了个别的插件,base64-weapp-qrcode.js,使用了一下,效果很不好,决定还是用回qrcode.js。
这里要说明一点,网上看了下很多案例,基本都要使用setTimeout()延迟来接收绘制后的图片路径。这样做不太好,第一想一次性绘制多张二维码的话,实现比较麻烦,第二,我们没法确保setTimeout里面的函数执行的时候二维码一定生成好了。
不过没关系,把插件改改就好了。

原生小程序实现支持async await

想要方便的实现在列表里面绘制多张二维码,首先得让你的微信小程序支持async await,这首先得用到runtime.js插件,git 地址:https://github.com/facebook/regenerator/blob/master/packages/regenerator-runtime/runtime.js,下下来以后,将runtime.js放到你的项目中(一般可以放到utils文件夹里面),然后页面通过import 引入即可

 import regeneratorRuntime from '../../utils/regenerator-runtime/runtime.js'

这里需要注意的一点是,你引入这个包后可能包会报错,这个时候找到runtime.js,翻到最下面,将try{}catch(){}部分注释掉即可。

在这里插入图片描述

qrcode.js中引入runtime.js

接下来对qrcode.js进行改造,首先要引入runtime.js。

import regeneratorRuntime from '../regenerator-runtime/runtime.js'

然后找到 qrcode.js里面的draw函数,更改如下

 draw: function (config) {
    
    
      //这里顺便把背景颜色,二维码颜色也做成参数,如果需要可以改变二维码颜色。由于参数数量增多,而且有多个并非必须参数,因此改为对象,方便取值。
      let {
    
     value, canvasId, cavW, cavH, $this, ecc, bkColor = '#ffffff', codeColor = '#000000' } = config
      var that = this;
      ecclevel = ecc || ecclevel;
      canvasId = canvasId || _canvas;
      if (!canvasId) {
    
    
        console.warn('No canvas provided to draw QR code in!')
        return;
      }
      var size = Math.min(cavW, cavH);
      value = that.utf16to8(value);//增加中文显示

      var frame = that.getFrame(value),
        // 组件中生成qrcode需要绑定this 
        ctx = wx.createCanvasContext(canvasId, $this),
        px = Math.round(size / (width + 8));
      var roundedSize = px * (width + 8),
        offset = Math.floor((size - roundedSize) / 2);
      size = roundedSize;
      ctx.clearRect(0, 0, cavW, cavW);
      ctx.setFillStyle(bkColor)
      ctx.fillRect(0, 0, cavW, cavW);
      ctx.setFillStyle(codeColor);
      for (var i = 0; i < width; i++) {
    
    
        for (var j = 0; j < width; j++) {
    
    
          if (frame[j * width + i]) {
    
    
            ctx.fillRect(px * (4 + i) + offset, px * (4 + j) + offset, px, px);
          }
        }
      }
      //这里也是关键,需要让函数返回一个promise对象,方便使用是使用await 接收
      return new Promise((resolve, reject) => {
    
    
        // console.log(canvas)
        /*ctx.draw可以接收两个参数,第一个参数是是否保留上一次的绘制结果,true为保留,false为不保留,这里选择不保留;
        第二个参数是绘制完成以后的回调函数,这里在绘制完成以后的回调函数里面,调用小程序的wx.canvasToTempFilePath API,直接获取到图片路径,并用resolve返出*/
        ctx.draw(false, function () {
    
    
          wx.canvasToTempFilePath({
    
    
            canvasId,
            success: function (res) {
    
    
              // console.log(res)
              let tempFilePath = res.tempFilePath;
              // console.log(tempFilePath)
              resolve(tempFilePath)
            },
            fail: function (res) {
    
    
              console.log(res)
            }
          })
        })

      })


    }

qrcode.js改造完成。

使用

在使用页面js文件引入qrcode.js

const QR = require('../../utils/externalUtils/qrcode.js')

从服务器请求到数据以后,循环调用qrcode的api,生成多张二维码,并将路径存储在数组中。这里注意传入的cavW 和cavH最好和canvas标签里设置的相同

let noUserdCards=await this.getNoUsedMyCards()
    for (let i = 0; i < noUserdCards.length; i++) {
    
    
      let imagePath = await QR.api.draw({
    
     value: noUserdCards[i].qrcode, canvasId: "myCardCanvas", cavW: 300, cavH: 300, })
      noUserdCards[i].imagePath = imagePath
    }
    this.setData({
    
    
      renderCards: noUserdCards
    })

在使用页面wxml里面加上canvas标签

<!-- 二维码canvas -->
<view class="canvas-box">
  <canvas style="width: 300px;height: 300px;background:#f1f1f1;" canvas-id="myCardCanvas" />
</view>

由于canvas标签只用于绘制二维码,不需要给客户看,真正给客户看的是绘制好的图片。所有使用窗口绝对定位将canvas标签扔到看不见的地方,切记不可以使用wx:if或者hidden来显示隐藏canvas,会有很多让你痛苦的坑,而且这样你基本拿不到canvas 对象

/*二维码canvas*/

.canvas-box {
    
    
  position: fixed;
  right: -100%;
  top: -100%;
}

至此,对qrcode.js的改造完成。
此次改造还有个遗憾,就是想加入支持带logo图片,目前尚未成功,求各位大神指点。

本次改造关键点:

1.引入runtime.js包,让原生小程序支持async await

2.修改qrcode.js里面的draw函数

2.1 返回promise对象,方便使用时是用await 接收
2.2 在draw函数绘制完成的回调函数里面,调用微信canvas 对象 api,wx.canvasToTempFilePath,直接将生成好的图片路径返回

猜你喜欢

转载自blog.csdn.net/qq_41000974/article/details/104008171
今日推荐