vue3+qrcode插件实现下载二维码图片(.png、.svg格式)

注释:qrcode可通过canvas的toDataURL方法下载对应的png图片,比较恶心的是下载svg格式(必须记录一下)

  1. 安装一下qrcode插件
npm i qrcode --save  或
yarn add qrcode
  1. 页面引入
import qrcode from 'qrcode'; // 引入qrcode
  1. vue文件使用
<div class="qrcode-box">
   	<canvas id="qrcode" ref="qrcodeRef" :width="qrCodeSize" :height="qrCodeSize" />
    <div id="qrcode-svg-container"></div>
</div>

<style scoped lang='less'>
.qrcode-box { // 无需显示二维码(隐藏处理)
    position: absolute;
    left: -999px;
    top: -999px;
}
</style>
  1. js 处理
<script setup lang='ts'>
import { reactive, ref, nextTick, onMounted, unref } from 'vue';

const qrAccURL = ref<string>(''); // 二维码内容地址

const qrcodeRef = ref<null>(); // 二维码DOM

const qrCodeSize = ref<number>(200); // 二维码大小

const qrCodeType = ref<number>(1); // 二维码类型 1为图片 2为svg

// 点击下载登记二维码事件
const onClickDownQrCodeButton = (size:number, type:number) => {
    qrCodeSize.value = size;
    qrCodeType.value = type;
    generateQRCode();
};

// 生成二维码的方法
const generateQRCode = () => {
    nextTick(()=>{
        const size = unref(qrCodeSize);
        const content = unref(qrAccURL);
        const downType = unref(qrCodeType);
        const canvas = qrcodeRef.value;
        canvas.width = size;
        canvas.height = size;
        canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
            qrcode.toCanvas(
            canvas,
            content,
            { width: size, marign: 10 },
            (res:any) => {
                console.log('回调:', res);
                const canvasData = document.getElementById('qrcode'); 
                const dataURL = canvasData.toDataURL(); //canvas获取的base64格式
                if(downType === 1){
                    handleDowndloadPng(dataURL);
                }else{
                    handleDownloadSvg(dataURL);
                }
            },
        );
    });
};

// 处理下载二维码png格式事件
const handleDowndloadPng = (ImgURL:any) =>{
    const size = unref(qrCodeSize);
    const link = document.createElement('a');
    link.style.display = 'none';
    link.href = ImgURL;
    link.setAttribute('download', `登记二维码尺寸:${size}x${size}`);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
};

// 处理下载二维码为svg格式事件
const handleDownloadSvg = (ImgURL:any) => {
    const size = unref(qrCodeSize);
    //svg 的dom节点(字符串)
    var svgString = `<svg id="downloadQrCodeSvg" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
    width="${size}px" height="${size}px"
    viewBox="0 0 ${size} ${size}" enable-background="new 0 0 ${size} ${size}" xml:space="preserve">
        <image id="image0" width="${size}" height="${size}" x="0" y="0" href="${ImgURL}"></image>
    </svg>`;
    const node = document.querySelector('#qrcode-svg-container');
    node.insertAdjacentHTML('afterbegin', svgString);
    console.log(node);
    setTimeout(()=>{
        const svgTagEl = document.querySelector('#downloadQrCodeSvg').outerHTML;
        downsvg(svgTagEl);
    }, 300);
};
const downsvg = (arg) => {
    const size = unref(qrCodeSize);
    var blob = new Blob([arg], { type: 'image/svg+xml;charset=utf-8' });
    var href = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = href;
    link.setAttribute('download', `登记二维码尺寸:${size}x${size}`);
    document.body.appendChild(link);
    link.click();
   document.body.removeChild(link);
};

这里暂未实现封装,感兴趣的可以自己考虑一下封装。谢谢!