源代码地址 : https://github.com/HYzihong/vue3_use_case
git: https://github.com/HYzihong/vue3_use_case.gjt

引入 qrcode-vue3


pnpm i qrcode-vue3 -D

自定义qrcode组件

<!--
 * @Author: hy
 * @Date: 2022-02-08 23:20:29
 * @LastEditors: hy
 * @Description: 
 * @LastEditTime: 2022-02-08 23:23:26
 * @FilePath: /vue3UseCase/src/views/qrcode/components/QrOcde.vue
 * Copyright 2022 hy, All Rights Reserved. 
 * 仅供学习使用~
-->

<template>
  <div>
    <div v-if="imageUrl" :class="containerClass">
      <img :src="imageUrl" :class="imageClass" @click="downloadImage" crossorigin="anonymous" />
    </div>
  </div>
</template>
<script lang="ts" setup>
  // https://www.npmjs.com/package/qrcode-vue3
  import QRCodeStyling from 'qrcode-vue3/src/core/QRCodeStyling';
  import { onMounted, ref, watch } from 'vue';
  import { donwloadBase64Image } from '../hooks/useDownLoadBase64Image';
  //props
  const props = defineProps({
    width: {
      type: Number,
      default: 300,
    },
    imageClass: {
      type: String,
      default: '',
    },
    containerClass: {
      type: String,
      default: '',
    },
    downloadButton: {
      type: String,
      default: '',
    },
    buttonName: {
      type: String,
      default: 'Download3',
    },
    height: {
      type: Number,
      default: 300,
    },
    value: {
      type: String,
      required: true,
    },
    image: {
      type: String,
      default: '',
    },
    qrOptions: {
      type: Object,
      default: () => ({
        typeNumber: 0,
        mode: 'Byte',
        errorCorrectionLevel: 'Q',
      }),
    },
    imageOptions: {
      type: Object,
      default: () => ({ hideBackgroundDots: true, imageSize: 0.4, margin: 0 }),
    },
    dotsOptions: {
      type: Object,
      default: () => ({
        type: 'dots',
        color: '#6a1a4c',
        gradient: {
          type: 'linear',
          rotation: 0,
          colorStops: [
            { offset: 0, color: '#6a1a4c' },
            { offset: 1, color: '#6a1a4c' },
          ],
        },
      }),
    },
    backgroundOptions: {
      type: Object,
      default: () => ({ color: '#ffffff' }),
    },
    cornersSquareOptions: {
      type: Object,
      default: () => ({ type: 'dot', color: '#000000' }),
    },
    cornersDotOptions: {
      type: Object,
      default: () => ({ type: undefined, color: '#000000' }),
    },
    fileExt: {
      type: String,
      default: 'png',
    },
    download: {
      type: Boolean,
      default: false,
    },
    fileName: {
      type: String,
      default: '二维码.png',
    },
    downloadOptions: {
      type: Object,
      default: () => ({ name: 'vqr', extension: 'png' }),
    },
  });

  const imageUrl = ref<string>('');
  const qrCode = ref(
    new QRCodeStyling({
      data: props.value,
      width: props.width,
      height: props.height,
      qrOptions: props.qrOptions,
      imageOptions: props.imageOptions,
      dotsOptions: props.dotsOptions,
      backgroundOptions: props.backgroundOptions,
      image: props.image,
      cornersSquareOptions: props.cornersSquareOptions,
      cornersDotOptions: props.cornersDotOptions,
    }),
  );
  watch(
    () => props.value,
    async () => {
      qrCode.value = new QRCodeStyling({
        data: props.value,
        width: props.width,
        height: props.height,
        qrOptions: props.qrOptions,
        imageOptions: props.imageOptions,
        dotsOptions: props.dotsOptions,
        backgroundOptions: props.backgroundOptions,
        image: props.image,
        cornersSquareOptions: props.cornersSquareOptions,
        cornersDotOptions: props.cornersDotOptions,
      });

      imageUrl.value = await qrCode.value.getImageUrl(props.fileExt);
    },
  );
  onMounted(async () => {
    imageUrl.value = await qrCode.value.getImageUrl(props.fileExt);
  });
  function downloadImage(): void {
    console.log('base64 data =>', imageUrl.value);
    if (props.download) {
      donwloadBase64Image(imageUrl, props.fileName);
    }
  }
</script>


自定义二维码下载


/*
 * @Author: hy
 * @Date: 2022-02-08 23:21:49
 * @LastEditors: hy
 * @Description:
 * @LastEditTime: 2022-02-08 23:22:10
 * @FilePath: /vue3UseCase/src/views/qrcode/hooks/useDownLoadBase64Image.ts
 * Copyright 2022 hy, All Rights Reserved.
 * 仅供学习使用~
 */

import { Ref } from 'vue';
// by https://blog.csdn.net/qq_35844177/article/details/79094249
export const donwloadBase64Image = (data: Ref<string>, fileName: string): void => {
  const aLink = document.createElement('a');
  const blob = base64ToBlob(data); //new Blob([content]);

  const evt = document.createEvent('HTMLEvents');
  evt.initEvent('click', true, true); //initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为
  // @ts-ignore
  aLink.download = fileName;
  aLink.href = URL.createObjectURL(blob);
  aLink.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })); //兼容火狐
};
//base64转blob
function base64ToBlob(code: Ref<string>): any {
  const parts = code.value.split(';base64,');
  const contentType = parts[0].split(':')[1];
  const raw = window.atob(parts[1]);
  const rawLength = raw.length;

  const uInt8Array = new Uint8Array(rawLength);

  for (let i = 0; i < rawLength; ++i) {
    uInt8Array[i] = raw.charCodeAt(i);
  }
  return new Blob([uInt8Array], { type: contentType });
}

Logo

前往低代码交流专区

更多推荐