一、项目目标与应用场景
本文将封装一个功能全面的二维码工具组件,包含:
- ✅ 文本转二维码
- ✅ 下载二维码图片
- ✅ 上传图片识别二维码
- ✅ 支持颜色/尺寸配置
- ✅ Base64/链接识别
- ✅ 摄像头扫码识别(实时识别)
适用于后台管理、文档系统、支付系统、设备绑定等场景。
二、安装依赖 & 技术选型
主要技术栈如下:
qrcode
:二维码生成jsQR
:识别二维码vue-demi
:Vue 2/3 兼容封装(可选)@zxing/library
:摄像头扫码支持
安装:
npm install qrcode jsqr @zxing/library
三、项目结构(Mermaid)
graph TD
A[QrCodeBox.vue] --> B[生成二维码区域]
A --> C[上传图片识别]
A --> D[摄像头扫码]
B --> E[qrcode库生成Canvas]
C --> F[jsQR识别图片]
D --> G[@zxing读取摄像头流]
四、二维码工具组件封装(QrCodeBox.vue)
<template>
<div class="qr-code-box">
<input v-model="text" placeholder="请输入文本" />
<div>
<label>尺寸:</label>
<input type="number" v-model="size" min="100" />
<label>颜色:</label>
<input type="color" v-model="color" />
</div>
<canvas ref="canvasRef"></canvas>
<button @click="generate">生成二维码</button>
<button @click="download">下载</button>
<hr />
<input type="file" accept="image/*" @change="onFileChange" />
<p v-if="result">识别结果:{{ result }}</p>
<hr />
<div v-if="cameraSupported">
<video ref="videoRef" autoplay muted playsinline width="200" />
<button @click="startCamera">打开摄像头扫码</button>
<button @click="stopCamera">关闭摄像头</button>
<p v-if="liveResult">扫码结果:{{ liveResult }}</p>
</div>
</div>
</template>
<script setup>
import { ref, onUnmounted } from 'vue'
import QRCode from 'qrcode'
import jsQR from 'jsqr'
import { BrowserMultiFormatReader } from '@zxing/library'
const text = ref('')
const size = ref(200)
const color = ref('#000000')
const canvasRef = ref(null)
const result = ref('')
const liveResult = ref('')
const videoRef = ref(null)
const codeReader = new BrowserMultiFormatReader()
let cameraRunning = false
const generate = async () => {
if (!text.value) return
await QRCode.toCanvas(canvasRef.value, text.value, {
width: size.value,
color: {
dark: color.value,
light: '#ffffff'
}
})
}
const download = () => {
const canvas = canvasRef.value
const link = document.createElement('a')
link.download = 'qrcode.png'
link.href = canvas.toDataURL('image/png')
link.click()
}
const onFileChange = async (e) => {
const file = e.target.files[0]
if (!file) return
const img = new Image()
const reader = new FileReader()
reader.onload = () => {
img.src = reader.result
img.onload = () => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = img.width
canvas.height = img.height
ctx.drawImage(img, 0, 0)
const imageData = ctx.getImageData(0, 0, img.width, img.height)
const code = jsQR(imageData.data, img.width, img.height)
result.value = code?.data || '未识别出二维码'
}
}
reader.readAsDataURL(file)
}
const startCamera = async () => {
if (cameraRunning) return
try {
cameraRunning = true
const videoInputDevices = await codeReader.listVideoInputDevices()
const selectedDeviceId = videoInputDevices[0]?.deviceId
codeReader.decodeFromVideoDevice(selectedDeviceId, videoRef.value, (res, err) => {
if (res) {
liveResult.value = res.getText()
}
})
} catch (e) {
console.error('摄像头扫码失败', e)
}
}
const stopCamera = () => {
cameraRunning = false
codeReader.reset()
}
onUnmounted(() => stopCamera())
const cameraSupported = 'mediaDevices' in navigator
</script>
<style scoped>
.qr-code-box {
display: flex;
flex-direction: column;
gap: 1rem;
}
</style>
五、功能展示与优化建议
功能点 | 状态 |
---|---|
文本生成二维码 | ✅ 支持 |
自定义颜色/大小 | ✅ 支持 |
下载二维码图片 | ✅ 支持 |
图片识别二维码 | ✅ 支持 |
实时摄像头扫码 | ✅ 支持 |
移动端适配 | ✅ 支持 |
上传 Base64 链接 | ✅ 可扩展(decode URI) |
可扩展建议
- 支持拖拽上传识别图片
- 将组件抽离为 npm 包 / UI 插件
- 加入二维码背景图、中心图标
- 多语言支持
六、总结
通过整合 qrcode
、jsQR
和 @zxing/library
,我们实现了一个通用型二维码工具组件,适用于各类业务场景。无论是分享、扫码、登录、绑定设备,它都能帮你快速集成二维码功能。
后续可继续封装为 UI 库插件,或通过配置项拓展出多个二维码样式版本,提升组件复用性和灵活性。
到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕