vue3:使用:图片生成二维码并复制

实现在 vue3 中根据 url 生成一个二维码码,且可以复制。

注)复制功能 navigator.clipboard.write 只能在安全的localhost 这种安全网络下使用。https中需要添加安全证书,且在域名(例:https://www.baidu.com)这种下即可。

1、安装

注)由于qrcodejs的兼容性问题,需要在vue3中引入qrcodejs2-fix才能正常生成二维码。

复制代码
npm install qrcodejs2-fix

2、在vue文件中导入模块qrcodejs2-fix

复制代码
import QRCode from 'qrcodejs2-fix';

3、场景一、生成二维码码、复制(生成的二维码图片)

javascript 复制代码
<template>
    // 点南生成二维码
    <e-button type="primary" @click="handleGenerate">点击生成二维码</e-button>
    // 生成的二维码图片
    <div id="imgCode"></div>
    // 复制二维码
    <e-button type="primary" @click="handleCopyCode">复制</e-button>
</template>

<script setup>
// 1、生成二维码(id名称, 参数)
function handleGenerate(idName, name) {
    // 采集二维码:路径
    const ip = 'https://crm.waihucc.com';
    const getIPAddress = `${ip}/h5/index.html`; 
    const url = `${getIPAddress}?companyId=80&saleId=${name}`;
    // 获取二维码码 div 上的 id
    const qrCodeElement = document.getElementById(idName);
    if (qrCodeElement) {
        qrCodeElement.innerHTML = '';
        new QRCode(qrCodeElement, {
            text: url || '',
            width: 100, // 二维码宽度
            height: 100, // 二维码高度
        });
    }
}

// 2、复制生成的二维码(id 名称)
function handleCopyCode(idName) {
    // 1、获取图片元素
    const imgElement = document.querySelector(`#${idName} img`);
    // 2、创建一个新的Image对象
    const img = new Image();
    // 3、设置Image对象的src为图片元素的src
    img.src = imgElement.src;
    // 4、监听图片加载完成事件
    img.onload = function () {
        //(1)创建 Canvas
        const canvas = document.createElement('canvas');
        canvas.width = img.width;
        canvas.height = img.height;
        const ctx = canvas.getContext('2d');
        //(2)在Canvas上绘制图片
        ctx.drawImage(img, 0, 0);
        //(3)获取 Canvas 内容作为Blob
        canvas.toBlob(function (blob) {
            //(4)使用Clipboard API 把生成对象URL,写入到剪贴板
            navigator.clipboard
                .write([new ClipboardItem({ 'image/png': blob })])
                .then(() => {
                    ElMessage({
                        message: '二维码已复制',
                        type: 'success',
                    });
                })
                .catch(() => {
                    console.error('图像复制失败');
                });
        });
    };
}
</script>

4、场景二、点"复制"按钮,生成二维码,点击"复制"直接复制生成的二维码图片

javascript 复制代码
<template>
    // 复制二维码
    <e-button type="primary" @click="generateCode">复制</e-button>
    // 生成的二维码图片
    <div id="imgCode"></div>
</template>

<script setup>
// 1、
const generateCode = (url, idName) => {
    document.getElementById(idName).innerHTML = '';
    new QRCode(document.getElementById(idName), {
        text: url || '',
    });

    // 获取 Canvas 元素
    const canvas = document.getElementById(idName).querySelector('canvas');
    // 将 Canvas 转换为 Data URL
    const dataURL = canvas.toDataURL();
    // 创建一个 Blob 对象
    const blob = dataURLToBlob(dataURL);
    // 使用 Clipboard API 复制 Blob 对象到剪贴板
    navigator.clipboard
        .write([new ClipboardItem({ 'image/png': blob })])
        .then(() => {
            ElMessage({
                message: '二维码已复制',
                type: 'success',
            });
        })
        .catch(() => {
            console.error('图像复制失败');
        });
};

// 2、
const dataURLToBlob = (dataURL) => {
    const arr = dataURL.split(',');
    const mime = arr[0].match(/:(.*?);/)[1];
    const bstr = atob(arr[1]);
    let n = bstr.length;
    const u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], { type: mime });
};
</script>
相关推荐
Qrun28 分钟前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp28 分钟前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.1 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl3 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫5 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友5 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理7 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻7 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front8 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰8 小时前
纯flex布局来写瀑布流
前端·javascript·css