uni-app跨端生成二维码需用uQRCode等适配库,因qrcode.js依赖浏览器canvas在非H5端不可用;uQRCode封装了多端绘制与导出逻辑,支持一行代码获取临时路径或base64。
uni-app 里不能直接用 qrcode.js 生成图片
因为 qrcode.js 默认依赖浏览器的 canvas api,而 uni-app 的非 h5 端(如微信小程序、app)不支持原生 canvas dom 操作,直接引入会报 cannot read property 'getcontext' of null 或白屏。
真正能跨端生成二维码图片的,只有 uni-app 官方封装的 uni.canvasToTempFilePath + 自研绘图逻辑,或使用适配多端的轻量库(如 weapp-qrcode 或 uQRCode)。
- 微信小程序:必须用
canvas绘制,再调用uni.canvasToTempFilePath - H5 端:可用
qrcode.js直接输出canvas或img,但要注意 DOM 注入时机 - App 端(nvue):不支持普通
canvas,需改用native canvas或服务端生成 - 推荐优先用
uQRCode(专为 uni-app 写的,已处理多端差异)
用 uQRCode 动态生成二维码图片(推荐方案)
它把 canvas 绘制、临时文件转换、错误兜底都封装好了,一行代码就能拿到 base64 或临时路径,且支持 Promise。
安装:npm install uqrcodejs,然后在页面中:
import uQRCode from 'uqrcodejs'
调用示例:
uQRCode.make({
text: 'https://example.com?id=123',
size: 200,
margin: 4
}).then(res => {
// res.tempFilePath 是小程序/App 的临时路径,H5 下是 base64
this.qrCodeUrl = res.tempFilePath
})
-
text必填,必须是字符串;若含中文,确保已 encodeURIComponent(uQRCode不自动编码) -
size单位是 px,建议设为偶数,避免某些端渲染模糊 -
margin是白边宽度,设为 0 可能导致扫码失败(部分扫码器要求留白) - 生成结果不是
data:URL,而是平台原生临时路径(小程序)或 base64(H5),直接赋给<image></image>src 即可
手动用 uni.createCanvasContext 绘制(仅限小程序)
如果你需要完全控制样式(比如加 logo、改颜色、圆角模块),就得自己画。但注意:这写法在 H5 和 App 端无效,必须配合条件编译。
关键步骤:
- 模板里加一个隐藏的
<canvas canvas-id="qrCanvas" style="width: 0; height: 0;"></canvas> - 用
uni.createCanvasContext('qrCanvas', this)获取上下文 - 先调用
qrcode.js的createQrCodeImg(需改写为返回点阵数据)或用uQRCode的getMatrix方法获取二维数组 - 遍历矩阵,用
fillRect逐块绘制黑点(注意坐标换算和像素对齐) - 最后调用
uni.canvasToTempFilePath导出图片
容易踩的坑:canvasToTempFilePath 必须在 draw 回调执行后调用,否则返回空路径;且 H5 下该 API 不存在,必须加 #ifdef MP-WEIXIN 包裹。
动态更新时别忘了清空 canvas 和重置状态
连续生成多个二维码时,如果复用同一个 canvas-id,旧内容可能残留,导致新码错乱或模糊。
- 每次生成前,先调用
context.clearActions()(如果用了save/restore) - 更稳妥的是:每次生成都新建一个带唯一
canvas-id的 canvas 节点,用完即删(v-if控制) - 如果用
uQRCode.make,它内部已处理清理,但你仍需确保传入的text是新值——别因为响应式没触发,还在用上一次的 data - 真机调试时,微信开发者工具可能缓存 canvas 输出,关掉「开启调试」再重试
最麻烦的其实是安卓微信里 canvas 渲染偏移、像素模糊,这时候与其硬调,不如把 size 提到 300+,再用 CSS 缩放控制显示大小。










