Vue+zxing实现扫二维码、条形码功能


// yarn add @zxing/library 安装zxing插件


<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> --> <!-- 扫码区域 --> <div class="QrCode"> <video ref="video" height="100%" width="100%" id="video" autoplay></video> </div> <!-- 扫码样式一 --> <!-- <div class="Qr_scanner"> <div class="box"> <div class="line_row"> <div class="line"></div> </div> <div class="angle"></div> </div> </div> --> <!-- 扫码样式二 --> <div class="qr-scanner"> <div class="box"> <div class="line"></div> <div class="angle"></div> </div> <div class="back-arrow" @click="clickIndexLeft"> <van-icon name="arrow-left" color="#fff" /> </div> </div> </div> </template> <script> // WebRTC适配器 只需要引入就ok import 'webrtc-adapter'; import { BrowserMultiFormatReader } from '@zxing/library' export default { name: 'scanCodePage', data() { return { codeReader: null, } }, mounted() { this.codeReader = new BrowserMultiFormatReader() this.openScan() }, beforeUnmount() { this.codeReader && this.codeReader.reset() }, methods: { async openScan() { // this.codeReader.listVideoInputDevices().then(videoInputDevices => { // // 默认获取第一个摄像头设备id // videoInputDevices.forEach((device) => // alert(`${device.label}, ${device.deviceId}`) // ) // let firstDeviceId = videoInputDevices[0].deviceId // this.codeReader && this.codeReader.reset() // 重置 // this.decodeFromInputVideoFunc(firstDeviceId) // }) // this.codeReader.getVideoInputDevices().then((videoInputDevices) => { this.codeReader.listVideoInputDevices().then((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.codeReader && this.codeReader.reset() // 重置 this.decodeFromInputVideoFunc(firstDeviceId) }).catch(err => { console.error(err) }) }, decodeFromInputVideoFunc(firstDeviceId) { this.codeReader.decodeFromInputVideoDeviceContinuously(firstDeviceId, 'video', (result, err) => { if (result) { console.log('扫描结果', result) if (result.text) { this.clickIndexLeft(result.text) } } if (err && !(err)) { console.error(err) } }) }, // 返回上一页 clickIndexLeft(result) { this.codeReader && this.codeReader.reset() this.codeReader = null this.$route.params.result = result this.$router.back() } } } </script> <style lang="scss" scope> // #region // .scan-index-bar{ // background-image: linear-gradient( -45deg, #42a5ff ,#59cfff); // } // .van-nav-bar__title{ // color: #fff !important; // } // #endregion /** 扫码样式一 */ .QrCode { width: 100vw; height: 100vh; position: relative; #video { width: 100%; height: 100%; object-fit: cover; } } // #region // .Qr_scanner { // position: fixed; // top: 0; // left: 0; // right: 0; // bottom: 0; // z-index: 9; // width: 100%; // height: 100%; // background-color: rgba(0, 0, 0, 0.5); // } // .Qr_scanner .box { // width: 75vw; // height: 75vw; // max-height: 75vh; // max-width: 75vh; // position: relative; // left: 50%; // top: 50%; // transform: translate(-50%, -50%); // border: 1px solid rgb(43, 113, 254); // .line_row { // width: 100%; // overflow: hidden; // background-image: linear-gradient( // 0deg, // transparent 24%, // rgba(136, 176, 255, 0.1) 25%, // rgba(136, 176, 255, 0.1) 26%, // transparent 27%, // transparent 74%, // rgba(136, 176, 255, 0.1) 75%, // rgba(136, 176, 255, 0.1) 76%, // transparent 77%, // transparent // ), // linear-gradient( // 90deg, // transparent 24%, // rgba(136, 176, 255, 0.1) 25%, // rgba(136, 176, 255, 0.1) 26%, // transparent 27%, // transparent 74%, // rgba(136, 176, 255, 0.1) 75%, // rgba(136, 176, 255, 0.1) 76%, // transparent 77%, // transparent // ); // background-size: 3rem 3rem; // background-position: -1rem -1rem; // animation: Heightchange 2s infinite; // animation-timing-function: cubic-bezier(0.53, 0, 0.43, 0.99); // animation-delay: 1.4s; // border-bottom: 1px solid rgba(136, 176, 255, 0.1); // display: flex; // justify-content: center; // align-items: flex-end; // } // } // .Qr_scanner .line { // width: 100%; // height: 3px; // background: #2b71fe; // // opacity: 0.58; // filter: blur(4px); // } // .Qr_scanner .box:after, // .Qr_scanner .box:before, // .Qr_scanner .angle:after, // .Qr_scanner .angle:before { // content: ""; // display: block; // position: absolute; // width: 78px; // height: 78px; // border: 0.3rem solid transparent; // } // .Qr_scanner .box:after, // .Qr_scanner .box:before { // top: -7px; // border-top-color: #2b71fe; // } // .Qr_scanner .angle:after, // .Qr_scanner .angle:before { // bottom: -7px; // border-bottom-color: #2b71fe; // } // .Qr_scanner .box:before, // .Qr_scanner .angle:before { // left: -7px; // border-left-color: #2b71fe; // } // .Qr_scanner .box:after, // .Qr_scanner .angle:after { // right: -7px; // border-right-color: #2b71fe; // } // @keyframes radar-beam { // 0% { // transform: translateY(-100%); // } // 100% { // transform: translateY(0); // } // } // @keyframes Heightchange { // 0% { // height: 0; // } // 100% { // height: 100%; // } // } // #endregion /** 扫码样式二 */ .qr-scanner { background-image: linear-gradient(0deg, transparent 24%, rgba(32, 255, 77, 0.1) 25%, rgba(32, 255, 77, 0.1) 26%, transparent 27%, transparent 74%, rgba(32, 255, 77, 0.1) 75%, rgba(32, 255, 77, 0.1) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(32, 255, 77, 0.1) 25%, rgba(32, 255, 77, 0.1) 26%, transparent 27%, transparent 74%, rgba(32, 255, 77, 0.1) 75%, rgba(32, 255, 77, 0.1) 76%, transparent 77%, transparent); background-size: 3rem 3rem; background-position: -1rem -1rem; // width: 100%; // height: 100%; // position: relative; // background-color: #111; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 9; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); } .qr-scanner .box { width: 75vw; height: 75vw; max-height: 75vh; max-width: 75vh; position: relative; left: 50%; top: 50%; transform: translate(-50%, -50%); overflow: hidden; border: 0.1rem solid rgba(0, 255, 51, 0.2); } .qr-scanner .line { height: calc(100% - 2px); width: 100%; background: linear-gradient(180deg, rgba(0, 255, 51, 0) 43%, #00ff33 211%); border-bottom: 3px solid #00ff33; transform: translateY(-100%); animation: radar-beam 2s infinite; animation-timing-function: cubic-bezier(0.53, 0, 0.43, 0.99); animation-delay: 1.4s; } .qr-scanner .box:after, .qr-scanner .box:before, .qr-scanner .angle:after, .qr-scanner .angle:before { content: ''; display: block; position: absolute; width: 3vw; height: 3vw; border: 0.2rem solid transparent; } .qr-scanner .box:after, .qr-scanner .box:before { top: 0; border-top-color: #00ff33; } .qr-scanner .angle:after, .qr-scanner .angle:before { bottom: 0; border-bottom-color: #00ff33; } .qr-scanner .box:before, .qr-scanner .angle:before { left: 0; border-left-color: #00ff33; } .qr-scanner .box:after, .qr-scanner .angle:after { right: 0; border-right-color: #00ff33; } @keyframes radar-beam { 0% { transform: translateY(-100%); } 100% { transform: translateY(0); } } .qr-scanner .back-arrow { position: fixed; top: 20px; left: 20px; width: 30px; height: 30px; border-radius: 100%; background-color: rgba(0, 0, 0, 0.3); z-index: 999; display: flex; justify-content: center; align-items: center; } </style>

  

posted @ 2021-11-12 09:56  fanmengfei  阅读(2578)  评论(0编辑  收藏  举报