vue实现扫码功能
使用vue-qrcode-reader库实现扫码
安装vue-qrcode-reader库,这是一个专为Vue设计的二维码扫描组件。通过npm或yarn安装:
npm install vue-qrcode-reader
在Vue组件中引入并使用:
<template>
<qrcode-stream @decode="onDecode" />
</template>
<script>
import { QrcodeStream } from 'vue-qrcode-reader'
export default {
components: { QrcodeStream },
methods: {
onDecode(decodedString) {
console.log(decodedString)
}
}
}
</script>
使用HTML5的getUserMedia API自定义实现
通过浏览器原生API访问摄像头,结合jsQR等库解析二维码:
<template>
<video ref="video" autoplay></video>
<button @click="stopScan">停止扫描</button>
</template>
<script>
import jsQR from 'jsqr'
export default {
data() {
return {
videoStream: null
}
},
mounted() {
this.startScan()
},
methods: {
async startScan() {
const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } })
this.$refs.video.srcObject = stream
this.videoStream = stream
this.scanFrame()
},
scanFrame() {
const canvas = document.createElement('canvas')
const video = this.$refs.video
canvas.width = video.videoWidth
canvas.height = video.videoHeight
const context = canvas.getContext('2d')
context.drawImage(video, 0, 0, canvas.width, canvas.height)
const imageData = context.getImageData(0, 0, canvas.width, canvas.height)
const code = jsQR(imageData.data, imageData.width, imageData.height)
if (code) {
console.log('扫描结果:', code.data)
this.stopScan()
} else {
requestAnimationFrame(this.scanFrame)
}
},
stopScan() {
this.videoStream.getTracks().forEach(track => track.stop())
}
}
}
</script>
移动端适配注意事项
在移动设备上需要处理横竖屏问题,建议添加以下CSS确保视频元素正确显示:
video {
width: 100%;
max-width: 100%;
height: auto;
object-fit: cover;
}
需要处理权限问题,建议添加用户拒绝权限时的回调:
startScan() {
navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => {
this.$refs.video.srcObject = stream
this.videoStream = stream
this.scanFrame()
})
.catch(err => {
console.error('摄像头访问被拒绝:', err)
})
}
性能优化建议
对于长时间运行的扫码功能,建议添加扫描间隔控制:
scanFrame() {
setTimeout(() => {
// 扫描逻辑
requestAnimationFrame(this.scanFrame)
}, 300) // 300ms扫描间隔
}
考虑添加扫描区域限制,减少图像处理范围:
context.drawImage(
video,
x, y, width, height, // 只绘制特定区域
0, 0, canvas.width, canvas.height
)






