template
<div class="qr-code qr-btn" @click="qrCodeSearch"> <i class="iconfont icon-weibiaoti--2"></i> </div>methods
qrCodeSearch() { this.$router.push( { name: 'scan' } )}
scan.vue
<template> <div class="page-scan" :style="{height: wrapHeight + 'px'}"> <div class="back" @click="goBack"> <img class="border-img" src="../../../../../assets/images/header/back.png" lazy-load="true" /> </div> <!-- 扫码区域 --> <video ref="video" id="video" class="scan-video" autoplay></video> <!-- 提示语 --> <div v-show="tipShow" class="scan-tip"> {{tipMsg}} </div> </div> </template> <script> import { BrowserMultiFormatReader } from '@zxing/library'; export default { name: 'scanCodePage', data() { return { wrapHeight: null, loadingShow: false, codeReader: null, scanText: '', vin: null, tipMsg: '正在尝试识别....', tipShow: false } }, created() { this.codeReader = new BrowserMultiFormatReader(); this.openScan(); }, destroyed(){ this.codeReader.reset(); }, watch: { '$route'(to, from) { if(to.path == '/scanCodePage'){ this.codeReader = new BrowserMultiFormatReader(); this.openScanTwo(); } } }, methods: { // 返回 goBack() { this.$destroy(); this.$router.back(); }, async openScan() { this.codeReader.getVideoInputDevices().then((videoInputDevices) => { this.tipShow = true; this.tipMsg = '正在调用摄像头...'; console.log('videoInputDevices', videoInputDevices); // 默认获取第一个摄像头设备id let firstDeviceId = videoInputDevices[0].deviceId; // 获取第一个摄像头设备的名称 const videoInputDeviceslablestr = JSON.stringify(videoInputDevices[0].label); if (videoInputDevices.length > 1) { // 判断是否后置摄像头 if (videoInputDeviceslablestr.indexOf('back') > -1) { firstDeviceId = videoInputDevices[0].deviceId; } else { firstDeviceId = videoInputDevices[1].deviceId; } } this.decodeFromInputVideoFunc(firstDeviceId); }).catch(err => { this.tipShow = false; this.codeReader = null; this.$destroy(); // 这部分接下去的代码根据需要,读者自行编写了 this.$router.push({ path: '/couponCancell', query: { couConsumerCode: '' } }) console.error(err); }); }, async openScanTwo() { this.codeReader = await new BrowserMultiFormatReader(); this.codeReader.getVideoInputDevices().then((videoInputDevices) => { this.tipShow = true; this.tipMsg = '正在调用摄像头...'; console.log('videoInputDevices', videoInputDevices); // 默认获取第一个摄像头设备id let firstDeviceId = videoInputDevices[0].deviceId; // 获取第一个摄像头设备的名称 const videoInputDeviceslablestr = JSON.stringify(videoInputDevices[0].label); if (videoInputDevices.length > 1) { // 判断是否后置摄像头 if (videoInputDeviceslablestr.indexOf('back') > -1) { firstDeviceId = videoInputDevices[0].deviceId; } else { firstDeviceId = videoInputDevices[1].deviceId; } } this.decodeFromInputVideoFunc(firstDeviceId); }).catch(err => { this.tipShow = false; this.$destroy(); // 下面代码根据业务需求自行编写 this.$router.push({ path: '/couponCancell', query: { couConsumerCode: '' } }) console.error(err); }); }, decodeFromInputVideoFunc(firstDeviceId) { this.codeReader.reset(); // 重置 this.scanText = ''; this.codeReader.decodeFromInputVideoDeviceContinuously(firstDeviceId, 'video', (result, err) => { this.tipMsg = '正在尝试识别...'; this.scanText = ''; if (result) { console.log('扫描结果', result); this.scanText = result.text; if (this.scanText) { this.tipShow = false; this.$destroy(); // 下面代码根据业务需求自行编写 this.$router.push({ path: '/couponCancell', query: { couConsumerCode: this.scanText } }) } } if (err && !(err)) { this.tipMsg = '识别失败'; setTimeout(() => { this.tipShow = false; this.$destroy(); // 下面代码根据业务需求自行编写 this.$router.push({ path: '/couponCancell', query: { couConsumerCode: '' } }) }, 2000) console.error(err); } }); } }, mounted() { this.wrapHeight = document.body.clientHeight; } } </script> <style lang="less" scoped> .page-scan .back{ position:absolute; top:10; left:10px; height:30px; z-index: 100; } .page-scan .back img{ height: 100%; } .scan-index-bar{ background-image: linear-gradient( -45deg, #42a5ff ,#59cfff); } .van-nav-bar__title{ color: #fff !important; } .scan-video{ height: 90vh; } .scan-tip{ width: 100vw; text-align: center; margin-bottom: 10vh; color: white; font-size: 5vw; } .page-scan{ overflow: hidden; background-color: #363636; } </style>