Skip to content

miniprogram-qrcode 二维码生成

关联清单:https://github.com/justjavac/awesome-wechat-weapp

业务常见诉求:在小程序内生成普通二维码(非“小程序码”),用于分享链接、会员码、核销码等。实现途径主要有三类:

  • A. 前端 Canvas 生成(第三方库)
  • B. 前端 Canvas 生成(纯算法 + 适配)
  • C. 后端生成二维码图片(PNG/SVG)下发到前端渲染

下文给出实现要点与最佳实践。

🎯 文章目标

  • 在小程序内用 Canvas 生成二维码并展示/保存
  • 理解第三方库选型与适配差异
  • 了解后端生成的优缺点与缓存策略

🧭 方案选择

  • 前端生成(A/B):无网络依赖、即时生成;对复杂容错级别/Logo 合成需做额外处理
  • 后端生成(C):后端统一控制样式/容错/水印/Logo,前端只展示,易于缓存与复用

🅰️ 方案A:第三方库(Canvas 绘制)

常见做法是使用专为小程序适配的二维码库(如 weapp-qrcode 等),调用 draw 方法输出到 canvas。不同库 API 略有差异,以下为通用示例(伪代码):

wxml
<!-- pages/qrcode/index.wxml -->
<canvas type="2d" id="qrcode" style="width: 240px; height: 240px"></canvas>
<button bindtap="save">保存到相册</button>
js
// pages/qrcode/index.js
import QR from '../../libs/weapp-qrcode.js' // 以实际库路径为准

Page({
  async onReady() {
    // 某些库需要传入 canvasId;若使用 2DCanvas,需先通过 selectorQuery 拿到 node
    const query = wx.createSelectorQuery()
    query.select('#qrcode')
      .fields({ node: true, size: true })
      .exec((res) => {
        const { node, width, height } = res[0]
        const ctx = node.getContext('2d')
        // 使用库的绘制方法(不同库用法不同,以下为示意)
        new QR({
          context: ctx,
          text: 'https://example.com/u/123',
          width, height,
          colorDark: '#000000',
          colorLight: '#ffffff',
          correctLevel: 'H'
        })
      })
  },

  save() {
    wx.canvasToTempFilePath({
      canvasId: 'qrcode',   // 若用旧版 canvasId 写法的库,传入对应 id;2DCanvas 需传 canvas 实例
      success: ({ tempFilePath }) => {
        wx.saveImageToPhotosAlbum({ filePath: tempFilePath })
      }
    })
  }
})

注意:

  • 小程序存在两套 Canvas 能力(旧版 wx.createCanvasContext 与新版 type="2d" 2DCanvas),不同库的适配不一,按库文档选择。
  • 真机与开发者工具渲染差异较大,务必在 iOS/Android 真机验证。

🅱️ 方案B:纯算法 + Canvas 适配

若需最小依赖,可引入纯 JS 的二维码算法(如 qrcode-generator 的小程序适配版),自行在 Canvas 上绘制模块(黑白方块):

  • 生成矩阵(二维数组)
  • 遍历矩阵并按比例绘制方块
  • 可叠加 Logo:先绘制二维码,再在中心绘制圆角 Logo

优点:可控性强,便于二次开发;缺点:实现复杂度较库方案高。

🅲 方案C:后端生成 + 前端展示

后端使用成熟库(如 qrcode/qrcodegen/ZXing 等)生成 PNG/SVG,通过 URL 下发到前端:

  • 前端 <image src="\{\{qrcodeUrl\}\}"> 即可展示
  • 支持 CDN 缓存、签名校验与过期策略
  • 易于加入水印、Logo 与防伪元素

适合需要大规模发码、统一风格治理与风控审计的场景。

🧩 工程与性能

  • 清晰的像素:确保 canvas 宽高与样式等比例,必要时放大 2x 绘制再缩放
  • 主题/容错级别:高容错(H)更抗污损,但码面更密集;酌情选择
  • 持久化:保存到相册需用户授权;业务内可缓存生成结果,降低重复计算

🧪 常见问题

  • 模糊/锯齿:样式宽高与 canvas 实宽高不一致;按比例放大绘制
  • 保存失败:检查 wx.canvasToTempFilePath 与相册权限
  • 库不兼容:确认使用的 Canvas 模式(2D/旧版),选择匹配的库版本

✅ 适用场景

  • 会员码、核销码、跳转链接分享
  • 离线生成与即时展示场景

🔗 参考

📊 总结

二维码生成在小程序内可通过“前端 Canvas”与“后端生成”两路实现。按业务规模与治理诉求选择:C 更利于统一与缓存,A/B 适合快速内生生成与离线场景。