使用插件:QR Code Styling
插件主页https://qr-code-styling.com/
插件github地址
使用该插件时需要拉取githu中的源码到本地后,自行编译,然后将编译后的入口文件存放到项目文件中进行使用。因为5+APP项目不支持操作DOM,所以必需修改部分源码才能正常运行。
由于这个插件的绘制需要依赖dom,所以在uniapp的5+APP项目中使用的,需要uniapp的renderjs,即在script标签中声明lang为renderjs。
我使用时是将这个插件封装成了一个组件,在每次使用时只需要通过父级传入二维码的配置即可生成二维码。
以下是主要思路:
- 父级传入配置项后,通知renderjs模块,并将新的配置项传入renderjs模块;
- 在renderjs模块中,使用QR Code Styling插件进行二维码的绘制
- 绘制结束后调用插件中的API将canvas转成blod文件并返回
- 将返回的blod文件转成base64编码,并在页面中的image元素使用该编码,完成二维码的渲染。
在开始使用插件前,主要需要解决的问题是renderjs的通信问题,因为是通过父级传入的二维码配置项。
<view :obj="obj" :change:obj="qrcode.setCodeStyle"></view>
<script>
export default {
props: {
config: {
type: Object,
default: () => {}
},
data() {
return {
obj: {},
};
},
watch: {
config: {
handler(newConfig, oldConfig) {
//需要判断data是否为空,否则父级在初始化时传入的config中data的默认值是空的话,可能会报错
if (newConfig.data) {
this.obj = newConfig
}
},
deep: true
}
}
}
</script>
<script module="qrcode" lang="renderjs">
import QRCodeStyling from "项目中存放QR Code Styling的路径"
export default {
methods: {
setCodeStyle(newConfig, oldConfig) {
}
}
}
</script>
到这里通信问题就解决了,接下来就是使用插件对二维码进行绘制。需要主要的是,由于5+APP项目不支持DOM的操作,而在源码项目中,src目录下的core文件加中的QRCanvas.ts中的loadImage函数中使用了Image元素的onload钩子。所以需要修改这部分的代码,用一个定时器替换掉。
到这里出现的问题就基本解决了。以下是完整的绘制二维码的代码片段。
<view :obj="obj" :change:obj="qrcode.setCodeStyle">
<u-image :src="qrcodeUrl"></u-image>
</view>
<script>
export default {
props: {
config: {
type: Object,
default: () => {}
},
data() {
return {
qrcodeUrl: "",
obj: {},
};
},
watch: {
config: {
handler(newConfig, oldConfig) {
//需要判断data是否为空,否则父级在初始化时传入的config中data的默认值是空的话,可能会报错
if (newConfig.data) {
this.obj = newConfig
}
},
deep: true
}
},
methods: {
qrCodeCallBack(value) {
this.qrcodeUrl = value.base64;
}
}
}
</script>
<script module="qrcode" lang="renderjs">
import QRCodeStyling from "项目中存放QR Code Styling的路径"
export default {
methods: {
setCodeStyle(newConfig, oldConfig) {
const that = this;
this.$nextTick(() => {
const options = newConfig;
const qrcodeEntity = new QRCodeStyling(options);
qrcodeEntity.getRawData().then(res => {
let reader = new FileReader();
reader.readAsDataURL(res);
reader.onload = function(e) {
//通过 UniViewJSBridge.publishHandler函数与组件本身的script模块进行通信,将二维码图片的base64传回
UniViewJSBridge.publishHandler('onWxsInvokeCallMethod', {
cid: that._$id,
method: 'qrCodeCallBack',
args: {
base64: e.target.result
}
})
}
})
})
}
}
}
</script>
到这二维码组件就完成了。以下是QR Code Styling插件的二维码配置项
qrcodeConfig: {
width: 600,
height: 600,
type: 'canvas', //有 svg 和canvas两个选项,如果在renderjs中使用,两种选项都可使用
data: '',
image: "", //logo图片地址 只能使用网络图片或者base64
margin: 10,
qrOptions: {
typeNumber: 10, //二维码密集程度
mode: 'Byte', //有Numeric Alphanumeric Byte Kanji四个选项;Kanji无法使用,其它三个选项无明显区别
errorCorrectionLevel: 'Q' //容错程度 由低到高 L M Q H
},
imageOptions: {
hideBackgroundDots: false, //是否遮挡二维码
imageSize: 0.3,
margin: 0,
crossOrigin: 'anonymous',
}, //logo的样式
dotsOptions: {
color: "#000",
// gradient: {
// type: 'linear', // 'radial'
// rotation: 180,
// colorStops: [{ offset: 0, color: 'rgb(207, 153, 68)' }, { offset: 1, color: 'rgb(240, 233, 204)' }]
// },
type: 'extra-rounded' // Square方形 Dots圆点 Rounded圆角 extra-rounded比Rounded更圆的圆角 classy只有一边的圆角 classy-rounded比classsy更圆的图形
}, //二维码的样式 包含码和码眼的点部分
backgroundOptions: {
color: "#fff",
// gradient: {
// type: 'linear', // 'radial'
// rotation: 0,
// colorStops: [{ offset: 0, color: '#ededff' }, { offset: 1, color: '#e6e7ff' }]
// },
},
cornersSquareOptions: {
color: '#35495E',
type: 'extra-rounded', //none圆角 square方形 dot圆形 extra-rounded比none更圆的圆角
// gradient: {
// type: 'linear', // 'radial'
// rotation: 180,
// colorStops: [{ offset: 0, color: '#25456e' }, { offset: 1, color: '#4267b2' }]
// },
}, //码眼的样式 只包含码眼的圈部分
cornersDotOptions: {
color: '#35495E',
type: 'dot', //none 左上右下圆角 square方形 dot圆
// gradient: {
// type: 'linear', // 'radial'
// rotation: 180,
// colorStops: [{ offset: 0, color: '#00266e' }, { offset: 1, color: '#4060b3' }]
// },
} //码眼的点样式 只包含码眼中间的点
},
最后,因为有插件的源码,所以如果需要绘制更丰富的样式,可以自行在源码中添加一些功能,比如绘制圆角背景、绘制边框、绘制文字等。
不过在5+APP中使用这个插件还是有一点缺陷的,这个缺陷就是用定时器替换了image的onload钩子,这样做可能会多出一些不可控性。