首先小程序本身没有绘制二维码的api,就需要用到weapp-qrcode这个库,下载地址:weapp-qrcode
1、首先去github上下载下来,主要用到的是/dist/weapp-qrcode.js这个js文件
2、定义好canvas和canvas-id 用 wx:if
将会消耗更多资源,因为每次呈现的时候他都会渲染,每次隐藏的时候,他都会销毁;如果用hidden
它是已经渲染的,只是控制显示隐藏,所以用hidden能够有更好的效果
<canvas style="margin:0 auto" hidden="{{!isShowQrCode}}" class="user-qrcode-modal-can" canvas-id="myQrcode1" ></canvas>
3、在对应js文件中引入weapp-qrcode.js
const drawQrcode = require('../../utils/QRcode.js');
4、使用drawQrcode将二维码绘制在canvas中
这里宽高不应该写死,应该是根据每个手机屏幕的宽高动态的设置,下面将会写到
drawQrcode({
width: 200,
height: 200,
ctx: wx.createCanvasContext('myQrcode1', this),
text: newVal,
})
5、完整代码
因为项目中用到的二维码地方比较多,所以封装成了一个组件,下面是完整的代码
drawQrcode.wxml
<!--components/pay_code/pay_code.wxml-->
<view class="user-qrcode-main-container">
<!-- <image class="user-qrcode-img" src="{{imagePath}}/docsmall/qrcode.png" catchtap="onClickQR"></image> -->
<view class="user-qrcode-modal-container" style="pointer-events: {{isShowModal ? 'auto' : 'none'}}">
<view class="bg-mk {{isShowModal ? 'bg-mk-ac' : ''}}" catchtap="onClickConfirm"></view>
<!--模态框主体-->
<view class="user-qrcode-modal-wraper {{isShowModal ?'user-qrcode-modal-wraper-active':'user-qrcode-modal-wraper-unactive'}}">
<!--核销二维码-->
<view class="code-content" wx:if="{{isShowModal}}">
<canvas style="margin:0 auto" hidden="{{!isShowQrCode}}" class="user-qrcode-modal-can" canvas-id="myQrcode1" ></canvas>
</view>
<view class="close" catchtap="onClickConfirm">X</view>
</view>
</view>
</view>
drawQrcode.wxss
/* components/pay_code/pay_code.wxss */
.user-qrcode-main-container{
margin-left: 20rpx;
width: 32rpx;
/* height: 32rpx; */
}
.mk-click{
position: absolute;
top: 0;
left: 0;
/* z-index: 99; */
width: 100%;
height: 100%;
}
.code-title{
font-size: 40rpx;
color: #666;
margin-top: 30rpx;
margin-bottom: 16rpx;
text-align: center;
}
.card-no{
font-size: 48rpx;
color: #666666;
font-weight: 600;
margin-bottom: 16rpx;
}
.user-qrcode-modal-container{
position: fixed;
display: flex;
justify-content: center;
align-items: center;
z-index: 99;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
/* background: rgba(0, 0, 0, .3); */
}
.bg-mk{
position: absolute;
top: 0;
left: 0;
z-index: -1;
width: 100vw;
height: 100vh;
opacity: 0;
transition: opacity cubic-bezier(0, 1.05, 0.6, 1.01) .3s;
background-color: rgba(255, 255, 255, 1);
}
.bg-mk-ac {
opacity: 1;
}
.bt-txt{
color: #666666;
font-size: 20rpx;
margin-top: 10rpx;
margin-bottom: 16rpx;
}
.close{
color: #db0629;
font-weight: bolder;
font-size: 35rpx;
/* margin-top: 30rpx; */
/* position: absolute;
top: 30rpx;
right: 30rpx;
z-index: 99; */
}
.user-qrcode-modal-wraper{
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 700rpx;
/* border-radius: 15px; */
overflow: hidden;
background: #fff;
transition: all 0.3s ease-in-out;
/* padding-left: 40rpx; */
}
.user-qrcode-modal-wraper-active{
transform: scale(1);
}
.user-qrcode-modal-wraper-unactive{
transform: scale(0);
}
.user-qrcode-img {
width: 120rpx;
height: 120rpx;
position: absolute;
top: 10rpx;
left: 10rpx;
z-index: 99;
}
.user-qrcode-modal-confirm-container{
width: 640rpx;
height: 100rpx;
line-height: 100rpx;
text-align: center;
font-size: 32rpx;
color: #1989fa;
}
.user-qrcode-modal-confirm-container:active{
background: rgb(224, 223, 223);
}
.code-content{
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
margin: 25rpx 0;
width: 670rpx;
height: 670rpx;
}
.user-qrcode-modal-can{
width: 670rpx;
height: 670rpx;
margin: 0 auto;
}
drawQrcode.js
const app = getApp();
const Util = require('../../utils/util.js');
const {
host
} = require('../../utils/httpUrlUtil.js');
const {
imageProPath
} = require('../../utils/imageUrlUtil.js');
const drawQrcode = require('../../utils/QRcode.js');
Component({
/**
* 组件的属性列表
*/
properties: {
code: {
type: String,
value: ''
},
isShowCode: {
type: Boolean,
value: false,
}
},
observers: {
isShowCode(newVal, oldVal) {
this.setData({
isShowModal: newVal
})
},
code(newVal, oldVal) {
console.log(newVal)
let that = this;
let showQrId = setTimeout(() => {
this.setData({
isShowQrCode: true
})
//我们这里需要根据每个手机屏幕的宽高动态的设置宽高乘以0.88是根据iPhone的宽高比例换算的
let { screenWidth } = wx.getSystemInfoSync();
drawQrcode({
width: screenWidth * 0.88,
height: screenWidth * 0.88,
ctx: that.qrCanvas,
//这里的text必须是一个字符串
text: newVal,
})
clearTimeout(showQrId)
}, 300)
}
},
/**
* 组件的初始数据
*/
data: {
//图片主路径
imagePath: imageProPath,
//是否展示模态框
isShowModal: false,
//是否展示二维码
isShowQrCode: false,
},
attached() {
this.qrCanvas = wx.createCanvasContext('myQrcode1', this);
},
/**
* 组件的方法列表
*/
methods: {
//点击X时触发
onClickConfirm(e) {
this.setData({
isShowQrCode: false,
isShowModal: false
})
}
}
})
这里在canvas中加一个判断是因为ios机型中,点击关闭后canvas的二维码不会消失 画布的宽和高尽量设置的大一点,不然扫码的时会扫不出来或者扫码失败
使用:在父组件中
不要忘记给父容器加相对定位
<view class="discount-item-container">
根据优惠券的唯一券码进行绘制
<pay_code hidden="{{discountInfo.couponType === 4}}" code="{{code}}" isShowCode="{{isShowQrCode}}" />
</view>
//点击优惠卷整体时触发
onClickDiscount(e) {
let { discountInfo } = this.data
console.log(discountInfo.couponType)
this.triggerEvent('onClickDiscount', discountInfo)
let tTimeid = setTimeout(() => {
if(discountInfo.couponType == 4){
this.setData({
isShowQrCode: true,
code: discountInfo.couponCode
})
}
}, 400)
this.setData({
isShowModal: true
})
},
这样就能绘制出来了
要保证二维码的周围都是没有东西的,灰色的蒙层有时候也不可以,所以我设置了一个白色的背景