Vue3-(二)Vue3实现扫码功能
本文最后更新于:March 15, 2022 pm
Vue(读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。与其它框架不同的是,Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层,方便与第三方库或既有项目整合。另一方面,Vue 完全有能力驱动采用单文件组件和Vue生态系统支持的库开发的复杂单页应用。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
目录
实现
支持二维码和条形码。
安装依赖
开源仓库:https://github.com/zxing-js/library
| npm install @zxing/library --save
|
组件
一访问本组件即可实现扫码功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
| <template> <div class="page-scan"> <!--返回--> <van-nav-bar title="扫描二维码/条形码" fixed @click-left="clickIndexLeft()" class="scan-index-bar"> <template #left> <van-icon name="arrow-left" size="18" color="#fff"/> <span style="color: #fff"> 取消 </span> </template> </van-nav-bar> <!-- 扫码区域 --> <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'; import { Dialog, Notify } from 'vant'; import { Toast } from 'vant';
export default { name: 'scanCodePage', data() { return { 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 == '/videoT'){ //本组件的url this.codeReader = new BrowserMultiFormatReader(); this.openScanTwo(); } } }, methods: { 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; 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; console.error(err); }); }, decodeFromInputVideoFunc(firstDeviceId) { this.codeReader.reset(); // 重置 this.scanText = ''; this.codeReader.decodeFromInputVideoDeviceContinuously(firstDeviceId, 'video', (result, err) => { this.tipMsg = '正在尝试识别...'; this.scanText = ''; if (result) { Toast.success('扫码成功') //vant的提示消息 console.log('扫描结果', result); this.scanText = result.text; console.log(result.text) if (this.scanText) { this.tipShow = false; // 这部分接下去的代码根据需要,读者自行编写了 // this.$store.commit('app/SET_SCANTEXT', result.text); // console.log('已扫描的小票列表', this.$store.getters.scanTextArr); console.log(result.text) this.clickIndexLeft() } return true } if (err && !(err)) { this.tipMsg = '识别失败'; setTimeout(() => { this.tipShow = false; }, 2000) console.error(err); } }); }, clickIndexLeft(){ // 返回上一页 // this.codeReader = null; // this.$destroy(); // this.$router.back(); if (window.history.length <= 1) { this.$router.push({path:'/'}) // return false //会影响上面,不能写返回false } else { this.$router.go(-1) } } } } </script>
<style lang="css"> .scan-index-bar{ background-image: linear-gradient( -45deg, #42a5ff ,#59cfff); } .van-nav-bar__title{ color: #fff !important; } .scan-video{ height: 80vh; } .scan-tip{ width: 100vw; text-align: center; margin-bottom: 10vh; color: white; font-size: 5vw; } .page-scan{ overflow-y: hidden; background-color: #363636; } </style>
|