Maison  >  Article  >  interface Web  >  Parlons de la façon dont Vue3+qrcodejs génère des codes QR et ajoute des descriptions textuelles

Parlons de la façon dont Vue3+qrcodejs génère des codes QR et ajoute des descriptions textuelles

青灯夜游
青灯夜游avant
2022-08-02 21:19:245207parcourir

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.

Parlons de la façon dont Vue3+qrcodejs génère des codes QR et ajoute des descriptions textuelles

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,二维码信息及文字描述都由外部传入

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

最后加上自定义文字即可

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

qrCodeOptionqrcode相关配置,详情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项目中的实用技巧记录

其中包括webpackvite遍历vue文件注册全局组件

调用组件

<template>
  <div>
    <qrcode></qrcode>
  </div>
</template>

效果如图

Parlons de la façon dont Vue3+qrcodejs génère des codes QR et ajoute des descriptions textuelles

多二维码遍历下载

上面补充的下载方法中,需要使用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

Générer un code QR h2>

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 CanvasEnfin, 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

Réfléchir et optimiser setTimeout pour Promesse

La fonction du code QR peut essentiellement être utilisée ici, mais je me demande pourquoi 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🎜rrreee

Appel du composant parent

Enregistrement global

🎜Vous pouvez enregistrer le composant en tant que composant global, vous pouvez vous référer à l'article Record de compétences pratiques dans le projet Vue🎜🎜🎜incluant webpack et vite Traversée du composant global d'enregistrement de fichier vue🎜

Composant d'appel

rrreee🎜L'effet est comme indiqué🎜🎜🎜

Téléchargement de traversée de codes QR multiples

🎜Dans la méthode de téléchargement ajoutée ci-dessus, vous devez utiliser 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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer