Vue移動端實現調用相機掃描二維碼或條形碼的全過程
一、開發前的準備
實現二維碼或條形碼的掃描識別比較普遍的做法是去調用微信 JS-SDK 的掃一掃功能(詳見 概述 | 微信開放文檔),或者支付寶 H5 開放的API(詳見 支付寶H5開放文檔)。
但是這兩者都會比較麻煩且有一定的局限性,微信的掃一掃隻能在微信裡用,而且還需要公眾號認證等配置操作。支付寶在內置 App 內可以同時識別二維碼和條形碼,但外部調用的 API 無法一次性同時識別,隻能分開識別。
我這裡就提供一個直接使用的開源庫:https://github.com/zxing-js/library,本人移動端前端開發的框架是 Vue,組件庫用的是 Vant,本文方案隻要開發時用的電腦具有攝像頭就可以實現效果預覽。
二、實現效果圖
這裡分享兩個在線工具
1、免費在線條形碼生成器-條碼生成制作工具
2、草料二維碼生成器 或者 點擊這裡
可以看到這樣操作不用經過任何打包(有的需要打包成 app 才行)、部署(有的需要部署到 https 的服務器才行)、配置(前面說的諸如微信開發的配置等…)。
三、具體操作實現
1、安裝。
npm install @zxing/library --save
2、假設場景:頁面上有個按鈕,點擊觸發掃碼功能 @click='scanCode()',在 methods 寫入該方法。
scanCode() { console.log('瀏覽器信息', navigator.userAgent); this.$router.push({ path: '/scanCodePage' }); }
同時在 vue-router 寫入對應頁面的路由。
{ title: '掃碼頁面', name: 'scanCodePage', path: '/scanCodePage', component: () => import('@/views/scanCodePage.vue') }
3、掃碼頁面代碼,通過與 video 標簽結合使用,把以下代碼直接全部拷貝到新建的一個 scanCodePage.vue 文件裡使用,讀者在註釋的地方自行根據需求,編寫後續的業務代碼即可。
<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'; 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 == '/scanCodePage'){ 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) { console.log('掃描結果', result); this.scanText = result.text; if (this.scanText) { this.tipShow = false; // 這部分接下去的代碼根據需要,讀者自行編寫瞭 // this.$store.commit('app/SET_SCANTEXT', result.text); // console.log('已掃描的小票列表', this.$store.getters.scanTextArr); } } if (err && !(err)) { this.tipMsg = '識別失敗'; setTimeout(() => { this.tipShow = false; }, 2000) console.error(err); } }); }, clickIndexLeft(){ // 返回上一頁 this.codeReader = null; this.$destroy(); this.$router.back(); } } } </script> <style lang="scss"> .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>
總結
到此這篇關於Vue移動端實現調用相機掃描二維碼或條形碼的文章就介紹到這瞭,更多相關Vue調用相機掃描二維碼內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 詳解vue之mixin的使用
- vue+video.js實現視頻播放列表
- 如何在vue中使用video.js播放m3u8格式的視頻
- js實現調用網絡攝像頭及常見錯誤處理
- vue3中的透傳attributes教程示例詳解