超简单的vue实现生成二维码并下载为图片(可直接复制使用)

背景

因为一些需求需要生成大量的二维码,用于用户核销使用,这里就用了一个比较使用的多的一个组件vue-qr.

效果

实际效果,大家可以去下面这个链接体验一下:

二维码生成工具体验网站

实现

一、添加依赖

npm install --save vue-qr

如果会报错,可以和我一样,直接引入指定版本,最新版本有一定几率不兼容。

npm install --save [email protected]

二、 前端页面实现

通过下面的语句引入组件

import VueQr from 'vue-qr'

核心功能代码: 

<script>
import VueQr from 'vue-qr'
export default {
  name: 'Index',
  components: {
    VueQr
  },
  data () {
    return {
      content: '', // 输入框输入的内容
      text: '', // 二
<think>我们需要在Vue实现一个功能:点击按钮复制vue-qrcode生成二维码图片到剪切板。 步骤: 1. 使用vue-qrcode生成二维码图片。 2. 获取该图片的DOM元素(img标签)。 3.图片转换为base64字符串(如果vue-qrcode已经生成的是base64,则可以直接使用)。 4. 创建一个新的canvas元素,将图片绘制到canvas上,然后使用canvas的toDataURL方法获取图片的base64数据(如果图片是svg格式,则需要转换,因为svg无法直接复制到剪贴板,通常我们将其转换为png格式)。 5. 使用navigator.clipboard.write方法将图片数据写入剪贴板(注意:这个方法需要安全上下文(HTTPS)或localhost)。或者,我们可以使用document.execCommand('copy')(已废弃,不推荐)或使用第三方库如clipboard-polyfill。 但是,由于vue-qrcode默认生成的是SVG元素,而SVG不能直接复制图片,所以我们需要将SVG转换为图片(如PNG)然后复制。 另一种思路:将SVG转换为Canvas,然后使用Canvas的toBlob或toDataURL得到PNG的base64数据,再复制。 具体步骤: 1. 使用vue-qrcode组件生成二维码给其一个ref属性,以便获取DOM。 2. 在按钮的点击事件中,执行复制操作。 3.复制函数中: a. 获取svg元素。 b. 将svg转换为字符串。 c. 创建一个Image对象,将svg作为其src(需要将svg字符串转换为DataURL)。 d.图片加载完成后,将其绘制到canvas上。 e. 使用canvas的toDataURL('image/png')获取PNG格式的base64字符串。 f. 将base64字符串转换为Blob。 g. 使用navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })])。 注意:navigator.clipboard.write方法可以写入多种类型的数据,但这里我们写入的是图片。另外,由于安全限制,这个方法可能在某些浏览器中不可用(比如非HTTPS环境),因此我们需要做兼容处理。 但是,由于Clipboard API的兼容性问题,我们也可以考虑使用一个隐藏的input或textarea来复制图片的URL(但这不是复制图片本身,而是复制图片的URL),或者使用第三方库如`clipboard-polyfill`来复制图片。 然而,我们的需求是复制图片,所以必须使用Clipboard API的图片复制功能。 由于步骤较为复杂,我们可以封装一个函数来实现svg转png复制。 另外,如果vue-qrcode支持直接生成canvas,那么我们可以直接使用canvas,这样更简单。但vue-qrcode默认是svg,我们可以通过修改它的props来生成canvas吗?查看vue-qrcode的文档,它默认是svg,但我们可以通过使用`renderAs`属性设置为'canvas'来生成canvas。 因此,更简单的方案是:将vue-qrcode的renderAs设置为'canvas',然后我们就可以直接获取canvas元素,然后将其转换为Blob复制。 所以,我们采用以下步骤(使用canvas方式): 1. 安装vue-qrcode(如果尚未安装):`npm install vue-qrcode` 2. 在组件中引入vue-qrcode,设置renderAs为'canvas'。 3.vue-qrcode一个ref,例如ref="qrcode"。 4. 在按钮点击事件中,通过ref获取canvas元素。 5. 使用canvas.toBlob方法获取Blob对象。 6. 使用navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]) 注意:如果canvas.toBlob不支持,我们可以用toDataURL然后转换。 但是,ClipboardItem目前只支持在较新的浏览器中使用,所以我们需要检查兼容性。 如果浏览器不支持,我们可以降级处理,比如提示用户右键保存图片。 代码实现如下(假设我们使用vue-qrcode的canvas渲染):</think>### 解决方案:点击按钮复制 vue-qrcode 生成二维码图片到剪贴板 #### 核心思路 1. **获取二维码图片**:将 vue-qrcode 生成的 SVG 转换为 PNG 格式(浏览器剪贴板不支持直接复制 SVG) 2. **复制到剪贴板**:使用 `navigator.clipboard.write()` API 写入图片数据 #### 完整代码实现 ```vue <template> <div> <!-- 二维码组件(使用 ref 获取 DOM) --> <vue-qrcode ref="qrcodeRef" :value="qrValue" :margin="0" /> <!-- 复制按钮 --> <button @click="copyQrCode">复制二维码图片</button> </div> </template> <script> import VueQrcode from 'vue-qrcode'; import { toCanvas } from 'qrcode' export default { components: { VueQrcode }, data() { return { qrValue: 'https://example.com' // 二维码内容 } }, methods: { async copyQrCode() { try { // 1. 获取 SVG 元素 const svgElement = this.$refs.qrcodeRef.$el; // 2. 将 SVG 转换为 Canvas const canvas = await this.svgToCanvas(svgElement); // 3. 从 Canvas 获取 Blob const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png') ); // 4. 复制到剪贴板 await navigator.clipboard.write([ new ClipboardItem({ 'image/png': blob }) ]); alert('二维码复制到剪贴板!'); } catch (error) { console.error('复制失败:', error); alert('复制失败,请使用现代浏览器'); } }, // SVG 转 Canvas 工具函数 svgToCanvas(svg) { return new Promise((resolve, reject) => { // 创建临时 Canvas const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 设置 Canvas 尺寸 canvas.width = svg.clientWidth; canvas.height = svg.clientHeight; // 创建 SVG 数据 URL const svgData = new XMLSerializer().serializeToString(svg); const img = new Image(); img.onload = () => { // 绘制到 Canvas ctx.fillStyle = 'white'; // 设置白色背景 ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0); resolve(canvas); }; img.onerror = reject; img.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgData)}`; }); } } } </script> ``` #### 关键步骤解释 1. **SVG 转 PNG 的必要性**: - 浏览器剪贴板 API 只支持复制位图格式(如 PNG/JPEG) - vue-qrcode 默认生成 SVG,需转换为 PNG 格式 2. **转换流程**: ```mermaid graph LR A[获取 SVG 元素] --> B[序列化为字符串] B --> C[创建 Image 对象] C --> D[绘制到 Canvas] D --> E[导出 PNG Blob] E --> F[写入剪贴板] ``` 3. **安全限制**: - `navigator.clipboard` 需要 HTTPS 环境(localhost 除外) - 旧版浏览器需使用 `document.execCommand('copy')` 降级方案(本例未展示) #### 替代方案(纯 Canvas) 如果允许直接使用 Canvas 生成二维码,可简化流程: ```vue <template> <div> <canvas ref="canvasRef"></canvas> <button @click="copyCanvas">复制二维码</button> </div> </template> <script> import { toCanvas } from 'qrcode' export default { mounted() { toCanvas(this.$refs.canvasRef, 'https://example.com') }, methods: { async copyCanvas() { this.$refs.canvasRef.toBlob(blob => { navigator.clipboard.write([ new ClipboardItem({ 'image/png': blob }) ]); }); } } } </script> ``` #### 常见问题解决 - **复制空白图片?** 确保在 Canvas 绘制时添加白色背景:`ctx.fillRect(0, 0, width, height)` - **安全错误(Clipboard API)?** 1. 检查是否为 HTTPS 或 localhost 2. 添加权限策略:`<meta http-equiv="Permissions-Policy" content="clipboard-write">` - **旧浏览器兼容**: 使用 `clipboard-polyfill` 库: ```javascript import * as clipboard from 'clipboard-polyfill' // 替换 navigator.clipboard.write: clipboard.write([new clipboard.ClipboardItem({ 'image/png': blob })]) ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值