聊聊Vue3+qrcodejs如何生成二维码并添加文字描述

 5120

Vue3如何更好地使用qrcodejs生成二维码并添加文字描述?下面本篇文章给大家介绍一下Vue3+qrcodejs生成二维码并添加文字描述,希望对大家有所帮助。


聊聊Vue3+qrcodejs如何生成二维码并添加文字描述


最近项目中有生成二维码功能的需求,还需要在二维码底部添加文字描述,并把二维码和文字合并成一张图下载的要求。

之前的项目有用到vue-qr,确实非常好用,但是考虑到添加文字描述,后面就选择了qrcodejs

生成二维码

安装qrcodejs,并安装其类型定义模块

  1. npm i qrcode -S
  2. npm install --save @types/qrcode

新建全局二维码组件QRcode.vue,二维码信息及文字描述都由外部传入

基本操作就是先调用qrcodetoDataURL方法,获取到二维码的Base64图片信息,随后新建Image,再把图片画到Canvas

最后加上自定义文字即可

需要注意的是文字的位置是在图片底部居中

qrCodeOptionqrcode相关配置,详情qrcode - npm (npmjs.com)

  1. <template>
  2.   <canvas id="canvas" ref="canvas" :width="width" :height="height"></canvas>
  3. </template>
  4.  
  5. <script setup>
  6. import QRCode from "qrcode";
  7. import { onMounted, ref } from "vue";
  8.  
  9. const props = defineProps({
  10.   //二维码存储内容
  11.   qrUrl: {
  12.     type: String,
  13.     default: "Hello World"
  14.   },
  15.   // canvas width
  16.   width: {
  17.     type: Number,
  18.     default: 400
  19.   },
  20.   // canvas height
  21.   height: {
  22.     type: Number,
  23.     default: 400
  24.   },
  25.   // 二维码尺寸(正方形 长宽相同)
  26.   qrSize: {
  27.     type: Number,
  28.     default: 360
  29.   },
  30.   // 二维码底部文字
  31.   qrText: {
  32.     type: String,
  33.     default: "Hello World"
  34.   },
  35.   //底部说明文字字号
  36.   qrTextSize: {
  37.     type: Number,
  38.     default: 24
  39.   }
  40. });
  41.  
  42. const qrCodeOption = {
  43.   errorCorrectionLevel: "H",
  44.   width: props.qrSize,
  45.   version: 7
  46. };
  47.  
  48. const canvas = ref<HTMLCanvasElement>();
  49. /**
  50.  * @argument qrUrl        二维码内容
  51.  * @argument qrSize       二维码大小
  52.  * @argument qrText       二维码中间显示文字
  53.  * @argument qrTextSize   二维码中间显示文字大小(默认16px)
  54.  */
  55. const handleQrcode = () => {
  56.   let dom = canvas.value as HTMLCanvasElement;
  57.   QRCode.toDataURL(props.qrUrl, qrCodeOption)
  58.     .then((url: string) => {
  59.       // 画二维码里的logo// 在canvas里进行拼接
  60.       const ctx = dom.getContext("2d") as CanvasRenderingContext2D;
  61.       const image = new Image();
  62.       image.src = url;
  63.       setTimeout(() => {
  64.         ctx.drawImage(image, (props.width - props.qrSize) / 2, 0, props.qrSize, props.qrSize);
  65.         if (props.qrText) {
  66.           //设置字体
  67.           ctx.font = "bold " + props.qrTextSize + "px Arial";
  68.           let tw = ctx.measureText(props.qrText).width; // 文字真实宽度
  69.           let ftop = props.qrSize - props.qrTextSize; // 根据字体大小计算文字top
  70.           let fleft = (props.width - tw) / 2; // 根据字体大小计算文字left
  71.           ctx.fillStyle = "#fff";
  72.           ctx.textBaseline = "top"; //设置绘制文本时的文本基线。
  73.           ctx.fillStyle = "#333";
  74.           ctx.fillText(props.qrText, fleft, ftop);
  75.         }
  76.       }, 0);
  77.     })
  78.     .catch((err: Error) => {
  79.       console.error(err);
  80.     });
  81. };
  82.  
  83. onMounted(() => {
  84.   handleQrcode();
  85. });
  86. </script>
  87.  
  88. <style scoped></style>


思考和优化setTimeout改为Promise

到这里二维码的功能基本可以使用了,但是我在想为什么这里需要使用到setTimeout呢?

如果是nextTick行不行?答案是不行的,原因是nextTick是微任务,实在DOM刷新之前就执行了,而setTimeout在之后执行。

可以注意到代码中有新建Image方法,图片加载是异步的,所以有更好的处理方法吗?

可以改用Promise,在图片的onload方法中返回图片就可以了,所以改写下handleQrcode

  1. const handleQrcode = () => {
  2.   let dom = canvas.value as HTMLCanvasElement;
  3.   QRCode.toDataURL(props.qrUrl, qrCodeOption)
  4.     .then((url: string) => {
  5.       // 画二维码里的logo// 在canvas里进行拼接
  6.       const ctx = dom.getContext("2d") as CanvasRenderingContext2D;
  7.       const image = new Image();
  8.       image.src = url;
  9.       new Promise<HTMLImageElement>((resolve) => {
  10.         image.onload = () => {
  11.           resolve(image);
  12.         };
  13.       }).then((img: HTMLImageElement) => {
  14.         // console.log(img, ctx)
  15.         ctx.drawImage(img, (props.width - props.qrSize) / 2, 0, props.qrSize, props.qrSize);
  16.         if (props.qrText) {
  17.           //设置字体
  18.           ctx.font = "bold " + props.qrTextSize + "px Arial";
  19.           let tw = ctx.measureText(props.qrText).width; // 文字真实宽度
  20.           let ftop = props.qrSize - props.qrTextSize; // 根据字体大小计算文字top
  21.           let fleft = (props.width - tw) / 2; // 根据字体大小计算文字left
  22.           ctx.fillStyle = "#fff";
  23.           ctx.textBaseline = "top"; //设置绘制文本时的文本基线。
  24.           ctx.fillStyle = "#333";
  25.           ctx.fillText(props.qrText, fleft, ftop);
  26.         }
  27.       });
  28.     })
  29.     .catch((err: Error) => {
  30.       console.error(err);
  31.     });
  32. };


二维码下载

有了二维码就需要下载,补充下载方法,在组件内部加

直接使用canvas toDataURL方法转成Base64

  1. //保存图片
  2. const savePic = () => {
  3.   let dom = canvas.value as HTMLCanvasElement;
  4.   let a = document.createElement("a");
  5.   //将二维码面板处理为图片
  6.   a.href = dom.toDataURL("image/png", 0.5);
  7.   a.download = props.qrUrl + ".png";
  8.   a.click();
  9. };
  10.  
  11. defineExpose({ savePic });


父组件调用

全局注册

可以把组件注册为全局组件,其中包括webpackvite遍历vue文件注册全局组件


调用组件

  1. <template>
  2.   <div class="container">
  3.     <QRcode />
  4.   </div>
  5. </template>


聊聊Vue3+qrcodejs如何生成二维码并添加文字描述


多二维码遍历下载

上面补充的下载方法中,需要使用defineExpose,不然会调用不到子组件方法

  1. <template>
  2.   <div>
  3.     <QRcode v-for="item in qrcodeList" ref="qrcode" :key="item.id" :qr-url="item.label" :qr-text="item.label" />
  4.     <el-button @click="downloadAll">downlaod</el-button>
  5.   </div>
  6. </template>
  7.  
  8. <script setup>
  9. import { reactive, ref } from "vue";
  10. const qrcode = ref();
  11. const qrcodeList = reactive([
  12.   { id: 1, label: "山卡拉OK" },
  13.   { id: 2, label: "伍六七" },
  14.   { id: 3, label: "梅小姐" },
  15.   { id: 4, label: "鸡大保" },
  16.   { id: 5, label: "小飞鸡" }
  17. ]);
  18.  
  19. const downloadAll = () => {
  20.   qrcode.value.map((item: any) => {
  21.     item.savePic();
  22.   });
  23. };
  24. </script>


Option Api案例

Option Api的案例如下

src/components/QRcodeOption.vue · LWH/vite-vue3-project - 码云 - 开源中国 (gitee.com)

src/views/qrcode/qrcode2.vue · LWH/vite-vue3-project - 码云 - 开源中国 (gitee.com)


本文网址:https://www.zztuku.com/detail-12885.html
站长图库 - 聊聊Vue3+qrcodejs如何生成二维码并添加文字描述
申明:本文转载于《掘金社区》,如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐

    实用文字遮罩3D效果