1.安装@zxing/library
npm i @zxing/library
2.页面引入
import { BrowserMultiFormatReader } from '@zxing/library';
3.实现步骤
3.1 显示摄像头的部分
<div class='AboutView'>
<!-- 镜头区域 -->
<video ref="video" id="video" class="scan-video" autoplay></video>
<div class="but_box">
<div> <span>机器编号:</span><input type="text" v-model="number"></div>
<div> <span>料 号:</span><input type="text" v-model="scanText"></div>
<div><button @click="openScan">扫码</button><button @click="postScanData">提交</button></div>
</div>
</div>
3.2 js代码
const codeReader = ref(null);
const scanText = ref('')
const number = ref('')
// 初始化相机
const openScan = ()=>{
codeReader.value = new BrowserMultiFormatReader()
codeReader.value.getVideoInputDevices().then(videoDevices=>{
let firstDeviceId = videoDevices[videoDevices.length - 1].deviceId;
if (videoDevices.length > 1) {
// 一般通过判断摄像头列表项里的 label 字段,'camera2 0, facing back' 字符串含有 'back' 和 '0',大部分机型是这样,如果有些机型没有,那就还是默认获取最后一个
firstDeviceId = videoDevices.find(el => { return el.label.indexOf('back') > -1 && el.label.indexOf('0') > -1 }) ?
videoDevices.find(el => { return el.label.indexOf('back') > -1 && el.label.indexOf('0') > -1 }).deviceId :
videoDevices[videoDevices.length - 1].deviceId;
}
decodeFromInputVideoFunc(firstDeviceId);
}).catch(err=>{
console.log(err);
})
}
// 扫码
const decodeFromInputVideoFunc = (firstDeviceId)=> { // 使用摄像头扫描
codeReader.value.reset(); // 重置
codeReader.value.decodeFromInputVideoDeviceContinuously(firstDeviceId, 'video', (result, err) => {
if (result) {
alert(result.text)
console.log('扫码结果', result);
scanText.value = result.text;
if (scanText.value) {
// 识别成功关闭摄像头
codeReader.value.reset()
codeReader.value.stopContinuousDecodeFromInputVideoDevice()
}
}
});
}
4.完整代码
<template>
<div class='AboutView'>
<!-- 镜头区域 -->
<video ref="video" id="video" class="scan-video" autoplay></video>
<div class="but_box">
<div> <span>机器编号:</span><input type="text" v-model="number"></div>
<div> <span>料 号:</span><input type="text" v-model="scanText"></div>
<div><button @click="openScan">扫码</button><button @click="postScanData">提交</button></div>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import { BrowserMultiFormatReader } from '@zxing/library';
// import axios from 'axios'
import { transferData } from '../server/common'
const codeReader = ref(null);
const scanText = ref('')
const number = ref('')
// 初始化相机
const openScan = ()=>{
codeReader.value = new BrowserMultiFormatReader()
codeReader.value.getVideoInputDevices().then(videoDevices=>{
let firstDeviceId = videoDevices[videoDevices.length - 1].deviceId;
if (videoDevices.length > 1) {
// 一般通过判断摄像头列表项里的 label 字段,'camera2 0, facing back' 字符串含有 'back' 和 '0',大部分机型是这样,如果有些机型没有,那就还是默认获取最后一个
firstDeviceId = videoDevices.find(el => { return el.label.indexOf('back') > -1 && el.label.indexOf('0') > -1 }) ?
videoDevices.find(el => { return el.label.indexOf('back') > -1 && el.label.indexOf('0') > -1 }).deviceId :
videoDevices[videoDevices.length - 1].deviceId;
}
decodeFromInputVideoFunc(firstDeviceId);
}).catch(err=>{
console.log(err);
})
}
// 扫码
const decodeFromInputVideoFunc = (firstDeviceId)=> { // 使用摄像头扫描
codeReader.value.reset(); // 重置
codeReader.value.decodeFromInputVideoDeviceContinuously(firstDeviceId, 'video', (result, err) => {
if (result) {
alert(result.text)
console.log('扫码结果', result);
scanText.value = result.text;
if (scanText.value) {
// 识别成功关闭摄像头
codeReader.value.reset()
codeReader.value.stopContinuousDecodeFromInputVideoDevice()
}
}
});
}
// 提交扫码结果
const postScanData = ()=>{
const scanData = {
partno:scanText.value,
deviceid:Number(number.value),
}
transferData(scanData).then(res=>{
alert(res)
})
}
onMounted(()=>{
})
</script>
<style scoped lang='scss'>
.AboutView {
}
video{
margin-top: 20%;
width: 80%;
}
.but_box{
position: fixed;
bottom: 10%;
left: 50%;
transform: translateX(-50%);
div{
display: flex;
margin: 0.125rem 0;
justify-content: space-around;
span{
width: 5.625rem;
text-align: right;
}
input{
text-align: center;
}
button{
width: 8.4375rem;
height: 2.75rem;
font-size: 1.5625rem;
font-weight: 600;
color: lavenderblush;
background-color: rgba(0, 183, 255,0.8);
border: none;
border-radius: 0.5rem;
}
}
}
</style>
5.效果图
6.注意:调用浏览器摄像头需要在https环境下运行