vue实现扫码
Vue 实现扫码功能
在 Vue 项目中实现扫码功能可以通过多种方式,常见的有使用第三方库或原生 API。以下是几种实现方法:
使用 vue-qrcode-reader 库
vue-qrcode-reader 是一个基于 WebRTC 的 Vue 组件,用于扫描二维码或条形码。
安装依赖:
npm install vue-qrcode-reader
基本用法:
<template>
<qrcode-stream @decode="onDecode"></qrcode-stream>
</template>
<script>
import { QrcodeStream } from 'vue-qrcode-reader'
export default {
components: { QrcodeStream },
methods: {
onDecode(decodedString) {
console.log(decodedString)
// 处理扫描结果
}
}
}
</script>
使用 Instascan 库
Instascan 是一个轻量级的纯 JavaScript 扫码库。
安装依赖:
npm install instascan
实现代码:
<template>
<video ref="preview"></video>
</template>
<script>
import Instascan from 'instascan'
export default {
mounted() {
const scanner = new Instascan.Scanner({
video: this.$refs.preview
})
scanner.addListener('scan', content => {
console.log(content)
// 处理扫描结果
})
Instascan.Camera.getCameras().then(cameras => {
if (cameras.length > 0) {
scanner.start(cameras[0])
} else {
console.error('未找到摄像头')
}
})
}
}
</script>
使用原生 HTML5 API
如果不想使用第三方库,可以使用原生 HTML5 的 MediaDevices API 和 JavaScript 扫码库。
示例实现:

<template>
<video ref="video" autoplay playsinline></video>
<canvas ref="canvas" style="display:none;"></canvas>
</template>
<script>
export default {
mounted() {
this.startScan()
},
methods: {
async startScan() {
const stream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'environment' }
})
this.$refs.video.srcObject = stream
// 这里需要集成一个扫码算法库
// 例如使用 jsQR: npm install jsqr
this.scanInterval = setInterval(() => {
this.detectQRCode()
}, 500)
},
detectQRCode() {
const canvas = this.$refs.canvas
const video = this.$refs.video
canvas.width = video.videoWidth
canvas.height = video.videoHeight
const ctx = canvas.getContext('2d')
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
// 使用 jsQR 检测二维码
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
const code = jsQR(imageData.data, imageData.width, imageData.height)
if (code) {
console.log('扫描结果:', code.data)
clearInterval(this.scanInterval)
// 处理扫描结果
}
}
},
beforeDestroy() {
if (this.scanInterval) clearInterval(this.scanInterval)
if (this.$refs.video.srcObject) {
this.$refs.video.srcObject.getTracks().forEach(track => track.stop())
}
}
}
</script>
注意事项
- 扫码功能需要在 HTTPS 环境或 localhost 下运行,否则摄像头访问可能被浏览器阻止
- 移动端设备可能需要处理横竖屏适配问题
- 部分安卓设备可能存在兼容性问题,需要测试不同机型
- 考虑添加权限请求失败的处理逻辑
- 性能优化:扫描频率不宜过高,避免影响页面性能
以上方法可以根据项目需求选择适合的实现方式。第三方库通常更简单易用,而原生 API 可以提供更多自定义控制。






