Vue3How to better use qrcodejs to generate QR codes and add text descriptions? The following article will introduce you to Vue3 qrcodejs to generate QR codes and add text descriptions. I hope it will be helpful to you.
In recent projects, there is a need to generate a QR code function. It is also necessary to add a text description at the bottom of the QR code and merge the QR code and text into one image for download. requirements.
The previous project used vue-qr
, which is really easy to use, but considering adding text description, I chose qrcodejs
later. (Learning video sharing: vue video tutorial)
The article project is based on "Practical Record of Using Vite to Build Vue3 Projects"
https://juejin.cn/ post/7082307153192550430
Installqrcodejs
, and install its type definition module
npm i qrcode -S npm install --save @types/qrcode
Create a new global QR code component QRcode.vue
. The QR code information and text description are passed in from the outside.
The basic operation is to first call qrcode
toDataURL method, obtain the
Base64 image information of the QR code, then create a new
Image, and then draw the image into
Canvas
qrCodeOption is the
qrcode related configuration , details
qrcode - npm (npmjs.com)
<template> <canvas></canvas> </template> <script> import QRCode from "qrcode"; import { onMounted, ref } from "vue"; const props = defineProps({ //二维码存储内容 qrUrl: { type: String, default: "Hello World" }, // canvas width width: { type: Number, default: 400 }, // canvas height height: { type: Number, default: 400 }, // 二维码尺寸(正方形 长宽相同) qrSize: { type: Number, default: 360 }, // 二维码底部文字 qrText: { type: String, default: "Hello World" }, //底部说明文字字号 qrTextSize: { type: Number, default: 24 } }); const qrCodeOption = { errorCorrectionLevel: "H", width: props.qrSize, version: 7 }; const canvas = ref<HTMLCanvasElement>(); /** * @argument qrUrl 二维码内容 * @argument qrSize 二维码大小 * @argument qrText 二维码中间显示文字 * @argument qrTextSize 二维码中间显示文字大小(默认16px) */ const handleQrcode = () => { let dom = canvas.value as HTMLCanvasElement; QRCode.toDataURL(props.qrUrl, qrCodeOption) .then((url: string) => { // 画二维码里的logo// 在canvas里进行拼接 const ctx = dom.getContext("2d") as CanvasRenderingContext2D; const image = new Image(); image.src = url; setTimeout(() => { ctx.drawImage(image, (props.width - props.qrSize) / 2, 0, props.qrSize, props.qrSize); if (props.qrText) { //设置字体 ctx.font = "bold " + props.qrTextSize + "px Arial"; let tw = ctx.measureText(props.qrText).width; // 文字真实宽度 let ftop = props.qrSize - props.qrTextSize; // 根据字体大小计算文字top let fleft = (props.width - tw) / 2; // 根据字体大小计算文字left ctx.fillStyle = "#fff"; ctx.textBaseline = "top"; //设置绘制文本时的文本基线。 ctx.fillStyle = "#333"; ctx.fillText(props.qrText, fleft, ftop); } }, 0); }) .catch((err: Error) => { console.error(err); }); }; onMounted(() => { handleQrcode(); }); </script> <style></style>
changed to
Promise
setTimeout needs to be used here?
nextTick, is that okay? The answer is no, the reason is that
nextTick is a microtask, which is actually executed before the DOM is refreshed, while
setTimeout is executed after.
Image method in the code. The image loading is asynchronous, so is there a better way to handle it?
Promise instead, just return the image in the
onload method of the image, so rewrite it as
handleQrcode
const handleQrcode = () => { let dom = canvas.value as HTMLCanvasElement; QRCode.toDataURL(props.qrUrl, qrCodeOption) .then((url: string) => { // 画二维码里的logo// 在canvas里进行拼接 const ctx = dom.getContext("2d") as CanvasRenderingContext2D; const image = new Image(); image.src = url; new Promise<htmlimageelement>((resolve) => { image.onload = () => { resolve(image); }; }).then((img: HTMLImageElement) => { // console.log(img, ctx) ctx.drawImage(img, (props.width - props.qrSize) / 2, 0, props.qrSize, props.qrSize); if (props.qrText) { //设置字体 ctx.font = "bold " + props.qrTextSize + "px Arial"; let tw = ctx.measureText(props.qrText).width; // 文字真实宽度 let ftop = props.qrSize - props.qrTextSize; // 根据字体大小计算文字top let fleft = (props.width - tw) / 2; // 根据字体大小计算文字left ctx.fillStyle = "#fff"; ctx.textBaseline = "top"; //设置绘制文本时的文本基线。 ctx.fillStyle = "#333"; ctx.fillText(props.qrText, fleft, ftop); } }); }) .catch((err: Error) => { console.error(err); }); };</htmlimageelement>
canvas toDataURLConvert the method to
Base64
//保存图片 const savePic = () => { let dom = canvas.value as HTMLCanvasElement; let a = document.createElement("a"); //将二维码面板处理为图片 a.href = dom.toDataURL("image/png", 0.5); a.download = props.qrUrl + ".png"; a.click(); }; defineExpose({ savePic });
Practical Tips Record in Vue Project
, includingwebpack and
viteTraversal
vueFile registration global component
<template> <div> <qrcode></qrcode> </div> </template>
defineExpose, otherwise the sub-component method
<template> <div> <qrcode></qrcode> <el-button>downlaod</el-button> </div> </template> <script> import { reactive, ref } from "vue"; const qrcode = ref(); const qrcodeList = reactive([ { id: 1, label: "山卡拉OK" }, { id: 2, label: "伍六七" }, { id: 3, label: "梅小姐" }, { id: 4, label: "鸡大保" }, { id: 5, label: "小飞鸡" } ]); const downloadAll = () => { qrcode.value.map((item: any) => { item.savePic(); }); }; </script>
The above is the detailed content of Let's talk about how Vue3+qrcodejs generates QR codes and adds text descriptions. For more information, please follow other related articles on the PHP Chinese website!