vue扫码功能实现
使用 vue-qrcode-reader 库实现扫码功能
安装 vue-qrcode-reader 库
npm install vue-qrcode-reader
在 Vue 组件中引入并使用
<template>
<div>
<qrcode-stream @decode="onDecode"></qrcode-stream>
<p>扫描结果: {{ result }}</p>
</div>
</template>
<script>
import { QrcodeStream } from 'vue-qrcode-reader'
export default {
components: { QrcodeStream },
data() {
return {
result: ''
}
},
methods: {
onDecode(decodedString) {
this.result = decodedString
}
}
}
</script>
使用 Html5Qrcode 实现扫码功能
安装 html5-qrcode 库
npm install html5-qrcode
Vue 组件实现
<template>
<div>
<div id="reader" style="width: 300px; height: 300px"></div>
<p>扫描结果: {{ result }}</p>
</div>
</template>
<script>
import { Html5Qrcode } from 'html5-qrcode'
export default {
data() {
return {
result: '',
html5QrCode: null
}
},
mounted() {
this.html5QrCode = new Html5Qrcode("reader")
const config = { fps: 10, qrbox: 250 }
this.html5QrCode.start(
{ facingMode: "environment" },
config,
this.onScanSuccess
).catch(err => {
console.error("扫码启动失败:", err)
})
},
beforeUnmount() {
this.html5QrCode.stop().then(() => {
console.log("扫码器已停止")
}).catch(err => {
console.error("停止扫码器失败:", err)
})
},
methods: {
onScanSuccess(decodedText) {
this.result = decodedText
}
}
}
</script>
使用原生 API 实现扫码功能
利用浏览器的 MediaDevices API 和 jsQR 库
npm install jsqr
Vue 组件实现
<template>
<div>
<video ref="video" autoplay playsinline></video>
<button @click="stopScan">停止扫描</button>
<p>扫描结果: {{ result }}</p>
</div>
</template>
<script>
import jsQR from 'jsqr'
export default {
data() {
return {
result: '',
videoStream: null,
animationFrame: null
}
},
mounted() {
this.startScan()
},
beforeUnmount() {
this.stopScan()
},
methods: {
async startScan() {
const stream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: "environment" }
})
this.videoStream = stream
this.$refs.video.srcObject = stream
this.scanQRCode()
},
scanQRCode() {
const video = this.$refs.video
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')
const scan = () => {
if (video.readyState === video.HAVE_ENOUGH_DATA) {
canvas.width = video.videoWidth
canvas.height = video.videoHeight
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) {
this.result = code.data
}
}
this.animationFrame = requestAnimationFrame(scan)
}
this.animationFrame = requestAnimationFrame(scan)
},
stopScan() {
if (this.animationFrame) {
cancelAnimationFrame(this.animationFrame)
}
if (this.videoStream) {
this.videoStream.getTracks().forEach(track => track.stop())
}
}
}
}
</script>
移动端扫码优化建议
添加权限请求处理
methods: {
async requestCameraPermission() {
try {
const permission = await navigator.permissions.query({ name: 'camera' })
permission.onchange = () => {
if (permission.state === 'granted') {
this.startScan()
} else {
console.warn('相机权限被拒绝')
}
}
} catch (err) {
console.warn('权限API不支持:', err)
}
}
}
添加扫描框UI指示
.qr-scanner-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 200px;
border: 2px solid #4CAF50;
background: rgba(0, 0, 0, 0.3);
}
常见问题处理
解决相机访问失败
navigator.mediaDevices.getUserMedia({
video: { facingMode: "environment" }
}).catch(err => {
console.error("无法访问相机:", err)
// 尝试使用用户前置摄像头
return navigator.mediaDevices.getUserMedia({
video: true
})
})
处理低光照环境
const constraints = {
video: {
facingMode: "environment",
torch: true, // 部分浏览器支持
brightness: { ideal: 0.8 }
}
}
这些方法提供了从简单到复杂的多种Vue扫码实现方案,可根据项目需求选择合适的方案。







