链接生成二维码组件
·
该组件是一个基于 Vue3 + TypeScript 开发的轻量化工具组件,核心功能为输入链接生成对应二维码,并提供二维码预览、链接复制、二维码下载等一站式操作,适用于会议分享、资源分发等需要快速将链接转化为可扫描形式的场景。
一、核心功能
1. 链接输入与实时响应
- 提供输入框支持自定义链接输入,默认填充示例链接(
https://example.com/share?room=123456&featureCodes=stream1,stream2),方便用户快速体验。 - 输入过程中触发防抖机制(延迟 500ms),避免频繁生成二维码导致性能消耗,输入完成后自动更新二维码(也可手动点击生成按钮触发)。
- 输入为空时给出友好警告提示,防止无效操作。
2. 二维码生成与预览
- 基于
qrcode库结合 Canvas 实现二维码生成,支持配置二维码尺寸(200x200px)、边距(2px)、容错级别(中等 M 级,兼顾识别率和体积)、颜色(黑色前景 + 白色背景,保证高对比度易扫描)。 - 生成成功后实时在页面展示二维码预览图,生成失败(如 Canvas 初始化异常、链接无效)给出明确错误提示。
- 支持链接动态更新:修改输入框链接后,重新生成的二维码会实时替换预览图。
3. 链接复制功能
- 点击「复制链接」按钮可将当前输入框中的链接复制到系统剪贴板。
- 复制成功 / 失败均有对应反馈提示,未输入有效链接时按钮禁用,防止误操作。
- 兼容主流浏览器的剪贴板 API,若浏览器不支持则提示手动复制。
4. 二维码下载功能
- 点击「下载二维码」按钮可将生成的二维码以 PNG 格式下载到本地,文件名为「分享二维码_时间戳.png」(时间戳确保文件名唯一)。
- 下载前自动校验二维码是否已生成,未生成时按钮禁用并给出警告提示。
- 下载完成后自动清理 DOM 临时元素和内存中的 URL 对象,避免内存泄漏。
二、技术特性
- 性能优化:通过防抖机制减少输入时的重复生成操作,Canvas 生成后复用元素,避免频繁创建销毁。
- 兼容性:基于标准 Canvas API 和剪贴板 API 开发,兼容 Chrome、Firefox、Edge、Safari 等主流浏览器。
- 用户体验:操作流程简洁(输入 → 生成 → 预览 / 复制 / 下载),所有关键操作均有反馈提示,按钮状态随场景动态禁用 / 启用。
- 资源清理:组件卸载时自动释放二维码图片 URL 内存、取消防抖定时器,避免内存泄漏。
三、使用场景
- 会议分享:将会议房间链接生成二维码,参会者扫码即可快速加入。
- 资源分发:将文件下载链接、网页地址转化为二维码,方便线下传播。
- 系统集成:可嵌入管理后台、会议系统等场景,提供链接快速转化工具。
四、必装依赖(npm 安装清单)
组件运行依赖以下 npm 包,需提前安装:
| 依赖包名 | 版本要求 | 作用说明 |
|---|---|---|
vue | ^3.2.0+ | Vue3 核心框架(组件基于 Vue3 语法开发) |
typescript | ^4.5.0+ | 类型校验,确保代码类型安全 |
qrcode | ^1.5.1+ | 核心二维码生成库,支持 Canvas 绘制 |
lodash-es | ^4.17.0+ | 提供防抖函数(优化输入时的性能) |
element-plus | ^2.0.0+ | UI 组件库(输入框、按钮、消息提示等) |
@types/lodash-es | ^4.17.0+ | lodash-es 的 TypeScript 类型声明文件 |
@types/qrcode | ^1.5.0+ | qrcode 库的 TypeScript 类型声明文件 |
安装命令(一键执行)
bash
运行
npm install vue@^3.2.0 typescript@^4.5.0 qrcode@^1.5.1 lodash-es@^4.17.0 element-plus@^2.0.0 @types/lodash-es@^4.17.0 @types/qrcode@^1.5.0 --save
补充说明
- 若项目已全局引入 Vue3、TypeScript 或 Element Plus,可跳过对应包的安装(确保版本兼容)。
- 类型声明文件(
@types/xxx)仅用于 TypeScript 项目,纯 JavaScript 项目可省略,但建议保留以获得更好的开发体验。 - 安装完成后,若 Element Plus 未全局注册,需在组件内单独引入样式(在
<script setup>开头添加):typescript
运行
import 'element-plus/dist/index.css'
示例图

代码如下:
<template>
<div class="qrcode-share-demo">
<h3>链接生成二维码示例</h3>
<!-- 链接输入区 -->
<el-input
v-model="shareLink"
placeholder="请输入需要生成二维码的链接"
class="link-input"
@input="debounceGenerateQrcode"
/>
<!-- 功能按钮区 -->
<div class="btn-group">
<el-button type="primary" @click="generateQrcode">生成二维码</el-button>
<el-button type="success" @click="copyLink" :disabled="!qrcodeSrc"
>复制链接</el-button
>
<el-button type="info" @click="downloadQrCode" :disabled="!qrcodeSrc"
>下载二维码</el-button
>
</div>
<!-- 二维码预览区 -->
<div class="qrcode-preview" v-if="qrcodeSrc">
<h4>二维码预览</h4>
<img :src="qrcodeSrc" alt="分享二维码" class="qrcode-img" />
</div>
<!-- 用于生成二维码的Canvas(隐藏) -->
<canvas ref="qrcodeCanvas" class="qrcode-canvas"></canvas>
</div>
</template>
<script setup lang="ts">
import { ref, onUnmounted, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import QRCode from 'qrcode' // 改用qrcode库
import { debounce } from 'lodash-es'
// 核心状态
const shareLink = ref<string>(
'https://example.com/share?room=123456&featureCodes=stream1,stream2',
)
const qrcodeSrc = ref<string>('') // 二维码图片URL
const qrcodeCanvas = ref<HTMLCanvasElement | null>(null) // Canvas元素
// 防抖生成二维码(输入延迟500ms执行)
const debounceGenerateQrcode = debounce(generateQrcode, 500)
/**
* 生成二维码(核心修复:使用qrcode库直接操作Canvas)
*/
async function generateQrcode() {
const link = shareLink.value.trim()
if (!link) {
ElMessage.warning('请输入有效的链接')
qrcodeSrc.value = ''
return
}
if (!qrcodeCanvas.value) {
ElMessage.error('Canvas元素初始化失败')
return
}
try {
// 清除Canvas原有内容
const ctx = qrcodeCanvas.value.getContext('2d')
if (ctx) {
ctx.clearRect(0, 0, qrcodeCanvas.value.width, qrcodeCanvas.value.height)
}
// 生成二维码到Canvas
await QRCode.toCanvas(qrcodeCanvas.value, link, {
width: 200, // 二维码尺寸
margin: 2, // 边距
errorCorrectionLevel: 'M', // 容错级别
color: {
dark: '#000000', // 二维码颜色
light: '#ffffff', // 背景色
},
})
// 将Canvas转换为图片URL(修复toDataURL报错问题)
qrcodeSrc.value = qrcodeCanvas.value.toDataURL('image/png', 1.0)
ElMessage.success('二维码生成成功')
} catch (err) {
console.error('生成二维码失败:', err)
ElMessage.error('生成二维码失败,请重试')
}
}
/**
* 复制链接到剪贴板
*/
function copyLink() {
const link = shareLink.value.trim()
if (!link) {
ElMessage.warning('无有效链接可复制')
return
}
navigator.clipboard
.writeText(link)
.then(() => ElMessage.success('链接复制成功'))
.catch(() => ElMessage.error('复制失败,请手动复制'))
}
/**
* 下载二维码图片
*/
function downloadQrCode() {
if (!qrcodeSrc.value) {
ElMessage.warning('暂无二维码可下载')
return
}
const a = document.createElement('a')
a.href = qrcodeSrc.value
const fileName = `分享二维码_${new Date().getTime()}.png`
a.download = fileName
document.body.appendChild(a)
a.click()
setTimeout(() => {
document.body.removeChild(a)
URL.revokeObjectURL(qrcodeSrc.value)
}, 100)
ElMessage.success('二维码下载成功')
}
// 组件卸载时清理资源
onUnmounted(() => {
if (qrcodeSrc.value) {
URL.revokeObjectURL(qrcodeSrc.value)
}
debounceGenerateQrcode.cancel()
})
// 初始化生成默认二维码
onMounted(() => {
// 确保Canvas元素已加载
setTimeout(generateQrcode, 100)
})
</script>
<style scoped>
.qrcode-share-demo {
max-width: 500px;
margin: 20px auto;
padding: 20px;
border: 1px solid #eee;
border-radius: 8px;
}
.link-input {
margin-bottom: 16px;
}
.btn-group {
margin-bottom: 20px;
display: flex;
gap: 10px;
}
.qrcode-preview {
text-align: center;
}
.qrcode-img {
width: 200px;
height: 200px;
border: 1px solid #eee;
padding: 10px;
border-radius: 4px;
}
/* 隐藏用于生成二维码的Canvas(仅后台生成用) */
.qrcode-canvas {
display: none;
width: 200px;
height: 200px;
}
h3 {
text-align: center;
margin-bottom: 20px;
}
</style>
更多推荐


所有评论(0)