Maison > Article > interface Web > Parlons de la façon dont Vue3+qrcodejs génère des codes QR et ajoute des descriptions textuelles
Vue3Comment mieux utiliser qrcodejs pour générer des codes QR et ajouter des descriptions textuelles ? L'article suivant vous présentera Vue3+qrcodejs pour générer des codes QR et ajouter des descriptions textuelles. J'espère que cela vous sera utile.
Dans les projets récents, il est nécessaire de générer une fonction de code QR. Il est également nécessaire d'ajouter une description textuelle au bas du code QR et de fusionner le code QR et le texte en une seule image pour le téléchargement.
Le projet précédent utilisait vue-qr
, qui est vraiment simple à utiliser, mais compte tenu de l'ajout d'une description textuelle, j'ai choisi qrcodejs
plus tard. (Partage de vidéos d'apprentissage : vue vidéo tutorielvue-qr
,确实非常好用,但是考虑到添加文字描述,后面就选择了qrcodejs
。(学习视频分享:vue视频教程)
文章项目基于 《使用Vite搭建Vue3项目实践记录 》
https://juejin.cn/post/7082307153192550430
安装qrcodejs
,并安装其类型定义模块
npm i qrcode -S npm install --save @types/qrcode
新建全局二维码组件QRcode.vue
,二维码信息及文字描述都由外部传入
基本操作就是先调用qrcode
的toDataURL
方法,获取到二维码的Base64
图片信息,随后新建Image
,再把图片画到Canvas
里
最后加上自定义文字即可
需要注意的是文字的位置是在图片底部居中
qrCodeOption
为qrcode
相关配置,详情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>
setTimeout
改为Promise
到这里二维码的功能基本可以使用了,但是我在想为什么这里需要使用到setTimeout
呢?
如果是nextTick
行不行?答案是不行的,原因是nextTick
是微任务,实在DOM刷新之前就执行了,而setTimeout
在之后执行。
可以注意到代码中有新建Image
方法,图片加载是异步的,所以有更好的处理方法吗?
可以改用Promise
,在图片的onload
方法中返回图片就可以了,所以改写下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 toDataURL
方法转成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 });
可以把组件注册为全局组件,可以参考文章Vue项目中的实用技巧记录
其中包括webpack
和vite
遍历vue
文件注册全局组件
<template> <div> <qrcode></qrcode> </div> </template>
效果如图
上面补充的下载方法中,需要使用defineExpose
)
Le projet d'article est basé sur "Utiliser Vite pour créer des enregistrements de pratiques de projet Vue3"
https://juejin.cn/post/7082307153192550430
Installez qrcodejs
et installez son module de définition de type <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>
Créez un nouveau composant de code QR global QRcode.vue
Les informations du code QR et la description textuelle sont importées depuis le. outside
L'opération de base consiste d'abord à appeler la méthode toDataURL
de qrcode
pour obtenir les informations d'image Base64
du code QR, puis à créer une nouvelle Image
, puis dessinez l'image dans Canvas
Enfin, ajoutez du texte personnalisé
Il est à noter que la position du texte est centrée en bas de l'image qrCodeOption
Pour la configuration liée au qrcode
, détails qrcode - npm (npmjs.com)rrreee
setTimeout
pour Promesse
setTimeout
doit être utilisé ici ? 🎜🎜Est-ce que ça va si c'est nextTick
? La réponse est non. La raison est que nextTick
est une microtâche et est en fait exécuté avant l'actualisation du DOM, tandis que setTimeout
est exécuté après. 🎜🎜Vous pouvez remarquer qu'il y a une nouvelle méthode Image
dans le code. Le chargement de l'image est asynchrone, alors existe-t-il une meilleure façon de le gérer ? 🎜🎜Vous pouvez utiliser Promise
à la place et renvoyer simplement l'image dans la méthode onload
de l'image, alors réécrivez-la sous la forme handleQrcode
🎜rrreeeTéléchargement du code QR🎜Si vous avez le code QR, vous devez le télécharger. Pour compléter la méthode de téléchargement, ajoutez 🎜🎜 à l'intérieur du champ. composant et utilisez directement canvas toDataURL
Méthode convertie en Base64
🎜rrreeewebpack
et vite
Traversée du composant global d'enregistrement de fichier vue
🎜defineExpose
, sinon la méthode des sous-composants ne sera pas appelé🎜rrreee🎜Cas Option Api🎜🎜Le cas d'Option Api est le suivant🎜 🎜🎜src/components/QRcodeOption.vue · LWH/vite-vue3-project - Code Cloud - Open Source Chine (gitee.com) 🎜🎜🎜🎜src/views/qrcode/qrcode2.vue · LWH/vite-vue3-project - Code Cloud - Open Source Chine (gitee.com)🎜🎜🎜 (Partage de vidéos d'apprentissage : 🎜développement web front-end🎜, 🎜 Vidéo de programmation de base🎜)🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!