首页 > 其他分享 >vue h5 扫码功能

vue h5 扫码功能

时间:2023-01-18 13:23:47浏览次数:43  
标签:扫码 vue scanner videoInputDevices h5 qr rgba transparent 摄像头

npm install @zxing/library --save

"@zxing/library": "^0.19.1",
<template>
    <div>
        <fixed-nav-bar @clickLeft="goBack" leftText="扫一扫"></fixed-nav-bar>
        <div class="page-scan">
            <div class="scan-box">
                <video ref="video" id="video" class="scan-video" autoplay></video>
                <div class="qr-scanner">
                    <div class="box">
                        <div class="line"></div>
                        <div class="angle"></div>
                    </div>
                </div>
                <div class="scan-tip">{{ scanTextData.tipMsg }}</div>
            </div>
        </div>
    </div>
</template>

<script>
  import fixedNavBar from "@/common/fixedNavbar"
  import { BrowserMultiFormatReader } from "@zxing/library";
  export default {
    name: "scanCodePage",
    components: {
      fixedNavBar,
    },
    data() {
      return {
        scanTextData: {
          codeReader: null,
          tipMsg: "识别二维码",
          // 这个,就是当前调用的摄像头的索引,为什么是6,我会在后面说的 华为手机是鸿蒙系统有8个摄像头
          num: 5,
          // 这个就是扫描到的摄像头的数量
          videoLength: ""
        },
        hasBind: false
      };
    },
    props: {
      show: {
        type: Boolean,
        default: false
      }
    },
    mounted() {
      this.scanTextData.codeReader = new BrowserMultiFormatReader();
      this.openScan(); // 打开摄像头
    },
    watch: {
      show(val) {
        if (!val) {
          // 关闭摄像头
          if (!document.getElementById("video")) {
            alert("请授权");
            return;
          }
          let thisVideo = document.getElementById("video");
          thisVideo.srcObject.getTracks()[0].stop();
          this.scanTextData.codeReader.reset();
        } else {
          if (this.scanTextData.codeReader === null) {
            this.scanTextData.codeReader = new BrowserMultiFormatReader();
          }
          this.openScan();
        }
      }
    },
    methods: {
      async openScan() {
        this.scanTextData.codeReader
          .getVideoInputDevices()
          .then(videoInputDevices => {
            // 默认获取第一个摄像头设备id
            let firstDeviceId = videoInputDevices[0].deviceId;
            console.log(
              "手机摄像头的数量",
              videoInputDevices.length,
              videoInputDevices
            );
            // 获取第一个摄像头设备的名称
            const videoInputDeviceslablestr = JSON.stringify(
              videoInputDevices[0].label
            );
            if (videoInputDevices.length > 1) {
              // 华为手机有6个摄像头,前三个是前置,后三个是后置,第6个摄像头最清晰
              if (videoInputDevices.length > 5) {
                firstDeviceId = videoInputDevices[5].deviceId;
              } else {
                // 判断是否后置摄像头
                if (videoInputDeviceslablestr.indexOf("back") > -1) {
                  firstDeviceId = videoInputDevices[0].deviceId;
                } else {
                  firstDeviceId = videoInputDevices[1].deviceId;
                }
              }
            }
            this.decodeFromInputVideoFunc(firstDeviceId);
          })
          .catch(err => {
            console.error(err);
          });
      },

      decodeFromInputVideoFunc(firstDeviceId) {
        this.scanTextData.codeReader.reset();
        this.scanTextData.codeReader.decodeFromInputVideoDeviceContinuously(
          firstDeviceId,
          "video",
          (result, err) => {
            if (result && result.text) {
              let content = result.text
              console.log("扫出的数据",content)
              if (content) {
                let uuidString = /^[a-zA-Z0-9]{32}$/
                if (content.indexOf('handover') > -1) {
                  //扫码签字
                  this.$router.push({
                    path: '/scanCodeAndSign',
                    query:{url:content}
                  })
                }else if (uuidString.test(content)) {
                  //设备详情
                  this.$router.push({
                    path: "/equipmentAccountDetail",
                    query: { unitBasicDeviceId: content },
                  })
                }else {
                  this.$toast("识别错误,请确认是否扫描的设备二维码~")
                }
              }
            }
            if (err && !err) {
              console.log(err);
              this.$toast.fail(err);
            }
          }
        );
      },
      async handleResult(scanResult) {
        console.log(scanResult);
        // TODO 逻辑处理或直接返回扫码结果
        this.$emit("getScanResult", scanResult);
      },
      goBack() {
        this.$router.go(-1)
      },
    },
    destroyed() {
      this.scanTextData.codeReader.reset(); // 重置摄像头
    }
  };
</script>

<style lang="less" scoped>
    .scan-box {
        position: fixed;
        top: 40px;
        left: 0;
        height: 100%;
        width: 100vw;
        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;
    }

    .scan-video {
        height: 95vh;
        width: 100vw;
        object-fit: cover;
    }

    .qr-scanner .box {
        width: 213px;
        height: 213px;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        overflow: hidden;
        border: 0.1rem solid rgba(0, 255, 51, 0.2);
        /* background: url('http://resource.beige.world/imgs/gongconghao.png') no-repeat center center; */
    }

    .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 alternate;
        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);
        }
    }

    .scan-tip {
        width: 100vw;
        text-align: center;
        margin-bottom: 5vh;
        color: white;
        font-size: 5vw;
        position: absolute;
        bottom: 50px;
        left: 0;
        color: #fff;
    }

    .page-scan {
        overflow-y: hidden;
    }
</style>

 

标签:扫码,vue,scanner,videoInputDevices,h5,qr,rgba,transparent,摄像头
From: https://www.cnblogs.com/Jishuyang/p/17059589.html

相关文章

  • Vue学习笔记
     Vue基础前置知识HTML+CSS+JavaSricpt+WebAPI(DOM+BOM)+Ajax创建Vue<script>newVue({  el:'#app',  data:{    message:'<h1>菜鸟教程<......
  • 前端框架对比总结(表格):React、Angular、Vue.js(国产)等
    前端框架对比前端框架优点缺点ReactReact是由Facebook开发和创建的开源框架。根据StackOverflowDeveloper的2021年调查,该框架是2022年最好的UI......
  • HBuilderX中 .vue解析
    1.<template>ui设计所有的有关界面的都写在这个里面2.<view>子标签,写在template中,view之间可以嵌套3.<script>js业务代码所有有关业务代码的都写在这个里面4.expoe......
  • VUEX 使用学习四 : action
    转载请注明出处:action用于处理异步任务;action,可以操作任意的异步操作,类似于mutations,但是是替代mutations来进行异步操作的。首先mutations中必须是同步方法,如果使用......
  • vue基本知识回顾 | this.$http.get 和 this.$http.post传参 / created与mounted区别 /
    vue基本知识回顾|this.$http.get和this.$http.post传参/created与mounted区别/富文本解析https://blog.csdn.net/feng2qing/article/details/126241834vue使......
  • 学习Vuex mutations
     Vuex中store数据改变的唯一方法就是提交 mutations。mutations里面装着一些改变数据方法的集合,这是Vuex设计很重要的一点,就是把处理数据逻辑方法全部放在 mutation......
  • vue中实现高德 地图定位功能
    index.html<template><divid="app"><divid="container"></div><div><p>经度:{{location.lng}}</p><p>纬度:{{location.lat}}</p>......
  • 企微应用H5调试及vConsole
    试想一下,你在应用的开发阶段时,你首次对接第三方平台,无法本地调试一些强制与平台绑定的代码,必须要在发版后,于线上环境进行alter调试,以及凭感觉猜测bug起因,再凭感觉进行代码......
  • vuex详解
    vuex的介绍vuex是vue.js应用程序中的状态管理模式,它是集中式存储管理所有组件的数据状态,vuex解决了多个视图之间的数据交互同步,不需要进行组件连接再传递数据。vuex的5大......
  • vue的基本使用
                                          ......