Home > Web Front-end > Vue.js > body text

Let's talk about how Vue3+qrcodejs generates QR codes and adds text descriptions

青灯夜游
Release: 2022-08-02 21:19:24
forward
5211 people have browsed it

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.

Let's talk about how Vue3+qrcodejs generates QR codes and adds text descriptions

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

Generate QR code

Installqrcodejs, and install its type definition module

npm i qrcode -S
npm install --save @types/qrcode
Copy after login

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

Finally add custom text

It should be noted that the position of the text is centered at the bottom of the picture

qrCodeOption is the qrcode related configuration , detailsqrcode - 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>
Copy after login

Thinking and optimizationsetTimeout changed to Promise

The function of QR code can basically be used here, but I am wondering why

setTimeout needs to be used here?

If it is

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.

You can notice that there is a new

Image method in the code. The image loading is asynchronous, so is there a better way to handle it?

You can use

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>
Copy after login

QR code download

Once you have the QR code, you need to download it. To supplement the download method, add

inside the component and use it directly

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 });
Copy after login

Parent component call

Global registration

You can put the component To register as a global component, you can refer to the article

Practical Tips Record in Vue Project

, including

webpack and viteTraversalvueFile registration global component

Calling component
<template>
  <div>
    <qrcode></qrcode>
  </div>
</template>
Copy after login

The effect is as shown

Lets talk about how Vue3+qrcodejs generates QR codes and adds text descriptions

多二QR code traversal download

In the download method added above, you need to use

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>
Copy after login
Option Api case## will not be called

#The case of Option Api is as follows

src/components/QRcodeOption.vue · LWH/vite-vue3-project - Code Cloud - Open Source China (gitee.com)

src/views/qrcode/qrcode2.vue · LWH/vite-vue3-project - Code Cloud - Open Source China (gitee.com)

(Learning video sharing:

webfrontenddevelopment

Basic programming video)

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!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template