Vue3Wie kann man qrcodejs besser nutzen, um QR-Codes zu generieren und Textbeschreibungen hinzuzufügen? Der folgende Artikel stellt Ihnen Vue3+qrcodejs vor, um QR-Codes zu generieren und Textbeschreibungen hinzuzufügen.
In neueren Projekten ist es erforderlich, eine QR-Code-Funktion zu generieren. Außerdem ist es erforderlich, am Ende des QR-Codes eine Textbeschreibung hinzuzufügen und den QR-Code und den Text zum Herunterladen in einem Bild zusammenzuführen .
Das vorherige Projekt verwendete vue-qr
, was wirklich einfach zu verwenden ist, aber ich dachte darüber nach, eine Textbeschreibung hinzuzufügen, und entschied mich später für qrcodejs
. (Teilen von Lernvideos: vue Video Tutorialvue-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
)
Das Artikelprojekt basiert auf „Verwenden von Vite zum Erstellen von Vue3-Projektpraxisaufzeichnungen“
https://juejin.cn/post/7082307153192550430
Installieren Sie qrcodejs
und installieren Sie das Typdefinitionsmodul<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>
QRcode.vue
. Die QR-Code-Informationen und die Textbeschreibung werden alle importiert von außen
Die grundlegende Operation besteht darin, zuerst die toDataURL
-Methode von qrcode
aufzurufen, um die Base64
-Bildinformationen des QR-Codes zu erhalten, und dann Erstellen Sie ein neues Bild
und zeichnen Sie das Bild dann in Leinwand
pictureqrCodeOption
Für qrcode
-bezogene Konfiguration, Details qrcode - npm (npmjs.com)
rrreee
setTimeout
auf PromisesetTimeout
hier verwendet werden muss? Ist es in Ordnung, wenn es nextTick
ist? Die Antwort ist nein. Der Grund dafür ist, dass nextTick
eine Mikrotask ist und tatsächlich ausgeführt wird, bevor das DOM aktualisiert wird, während setTimeout
danach ausgeführt wird. Sie können feststellen, dass der Code eine neue Image
-Methode enthält. Das Laden von Bildern erfolgt asynchron. Gibt es also eine bessere Möglichkeit, damit umzugehen? 🎜🎜Sie können stattdessen Promise
verwenden und das Bild einfach in der onload
-Methode des Bildes zurückgeben, also schreiben Sie es als handleQrcode
🎜rrreeeQR-Code-Download🎜Wenn Sie den QR-Code haben, müssen Sie ihn herunterladen. Fügen Sie zur Ergänzung der Download-Methode 🎜🎜 hinzu Komponente und verwenden Sie direkt canvas toDataURL
Methode konvertiert in Base64
🎜rrreeewebpack
und vite
Traversing vue
Dateiregistrierung globale Komponente🎜defineExpose
verwenden, andernfalls die Unterkomponentenmethode wird nicht aufgerufen. 🎜🎜🎜🎜src/views/qrcode/qrcode2.vue · LWH/vite-vue3-project – Code Cloud – Open Source China (gitee.com)🎜🎜🎜 (Lernvideo-Sharing: 🎜Web-Front-End-Entwicklung🎜, 🎜 Grundlegendes Programmiervideo🎜)🎜Das obige ist der detaillierte Inhalt vonLassen Sie uns darüber sprechen, wie Vue3+qrcodejs QR-Codes generiert und Textbeschreibungen hinzufügt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!