基于@zxing/library 扫码(健康码)(微信好友) (vue项目)

安装:

npm install @zxing/library

创建组件:

<template>
  <div class="qrcode">
    <video
      ref="video"
      id="video"
      class="scan-video"
      v-show="scanTextData.showScanBoxInfo"
      autoplay
    ></video>
    <div class="scan-img" v-show="scanTextData.showScanBoxInfo">
      <div class="scan-frame">
        <span class="left-t"></span>
        <span class="right-t"></span>
        <span class="left-b"></span>
        <span class="right-b"></span>
        <span class="cross-line"></span>
      </div>
    </div><div class="scan-tip" v-show="scanTextData.showScanBoxInfo">
      {{ scanTextData.tipMsg }}
    </div>
  </div>
</template>
<script>
import { BrowserMultiFormatReader } from "@zxing/library";
export default {
  name: "scanCodePage",
  data() {
    return {
      scanTextData: {
        loadingShow: false,
        codeReader: null,
        scanText: "",
        vin: null,
        tipMsg: "将二维码置于屏幕中,即可识别",
        tipShow: false,
        showScanBox: false,
        showScanBoxInfo: false,
      },
      hasBind: false,
      dataObj: { qrCodeId: undefined },
    };
  },
  components: {},
  created() {
    this.toScanCode();
  },
  destroyed() {
    this.scanTextData.codeReader.reset();
  },

  methods: {
    toScanCode() {
      console.log("识别二维码", this.dataObj);
      this.scanTextData.codeReader = new BrowserMultiFormatReader();
      this.scanTextData.showScanBox = true;
      this.openScan();
    },
    cancelScan() {
      //识别完停止使用摄像头
      let Video = document.getElementById("video");
      Video.srcObject.getTracks()[0].stop();
      this.scanTextData.codeReader.reset(); // 重置
      this.scanTextData.showScanBox = false;
      setTimeout(() => {
        this.scanTextData.showScanBoxInfo = false;
      }, 1000);
    },

    async openScan() {
      this.scanTextData.codeReader
        .getVideoInputDevices()
        .then((videoInputDevices) => {
          this.scanTextData.tipShow = true;
          this.scanTextData.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.scanTextData.tipShow = false;
          console.error(err);
        });
    },
    decodeFromInputVideoFunc(firstDeviceId) {
      this.scanTextData.codeReader.reset(); // 重置
      this.scanTextData.scanText = "";
      this.scanTextData.codeReader.decodeFromInputVideoDeviceContinuously(
        firstDeviceId,
        "video",
        (result, err) => {
          this.scanTextData.tipMsg = "将二维码置于屏幕中,即可识别";
          this.scanTextData.scanText = "";
          setTimeout(() => {
            this.scanTextData.showScanBoxInfo = true;
          }, 1000);
          if (result) {
            if (result.text) {
              let decodedText = result.text;
              // 返回出去的结果
              this.$emit('qrcodes',decodedText)
            }
          } else {
            // console.log('没出来?',result,err)
          }
          if (err && !err) {
            this.scanTextData.tipMsg = "识别失败";
            setTimeout(() => {
              this.scanTextData.tipShow = false;
            }, 2000);
            console.error(err);
          }
        }
      );
    },
  },
};
</script>

<style scoped lang="scss">
body {
  margin: 0;
  background-color: rgb(133, 133, 133);
}
.qrcode {
  position: relative;
  height: 100%;
  width: 100%;
  overflow: hidden;
}
.scan-index-bar {
  background-image: linear-gradient(-45deg, #42a5ff, #59cfff);
}
.van-nav-bar__title {
  color: #fff !important;
}
.scan-box {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 5;
  height: 100%;
  width: 100vw;
  .scan-cacel {
    position: absolute;
    top: 30px;
    left: 30px;
    z-index: 9;
    color: #fff;
    font-size: 35px;
  }
}
.scan-video {
  height: 100vh;
  width: 100vw;
  object-fit: cover;
}
.scan-img {
  width: 300px;
  height: 300px;
  position: fixed;
  top: 55%;
  left: 77%;
  margin-top: -200px;
  margin-left: -250px;
  z-index: 6;
  .scan-frame {
    width: 100%;
    height: 100%;
    position: relative;
    .left-t,
    .right-t,
    .left-b,
    .right-b {
      position: absolute;
      width: 80px;
      height: 80px;
    }
    .left-t {
      top: 0;
      left: 0;
      border-top: 2px solid #17b1b7;
      border-left: 2px solid #17b1b7;
    }
    .right-t {
      top: 0;
      right: 0;
      border-top: 2px solid #17b1b7;
      border-right: 2px solid #17b1b7;
    }
    .left-b {
      bottom: 0;
      left: 0;
      border-bottom: 2px solid #17b1b7;
      border-left: 2px solid #17b1b7;
    }
    .right-b {
      bottom: 0;
      right: 0;
      border-bottom: 2px solid #17b1b7;
      border-right: 2px solid #17b1b7;
    }
    .cross-line {
      width: 300px;
      height: 5px;
      background: linear-gradient(
        to right,
        rgba(255, 255, 255, 0),
        #5dddd3,
        rgba(255, 255, 255, 0)
      );
      position: absolute;
      top: 0;
      left: 0;
      animation: identifier_p 5s infinite;
    }
    @keyframes identifier_p {
      0% {
        top: 0%;
      }
      50% {
        top: 100%;
      }
      100% {
        top: 0;
      }
    }
  }
}
.scan-tip {
  width: 100vw;
  text-align: center;
  margin-bottom: 10vh;
  color: white;
  font-size: 5vw;
  position: absolute;
  bottom: 50px;
  left: 0;
  color: #fff;
}
.page-scan {
  overflow-y: hidden;
}
</style>



如果报错:Can’t enumerate devices, method not supported.

切记一件件事:扫码能运行在https,和本地上(用http://localhost:1314/,,不要用IP:192.168.xx.xx:1314)
切记一件件事:扫码能运行在https,和本地上(用http://localhost:1314/,,不要用IP:192.168.xx.xx:1314)
切记一件件事:扫码能运行在https,和本地上(用http://localhost:1314/,,不要用IP:192.168.xx.xx:1314)
切记一件件事:扫码能运行在https,和本地上(用http://localhost:1314/,,不要用IP:192.168.xx.xx:1314)
切记一件件事:扫码能运行在https,和本地上(用http://localhost:1314/,,不要用IP:192.168.xx.xx:1314)
切记一件件事:扫码能运行在https,和本地上(用http://localhost:1314/,,不要用IP:192.168.xx.xx:1314)
切记一件件事:扫码能运行在https,和本地上(用http://localhost:1314/,,不要用IP:192.168.xx.xx:1314)

http是不行的

如果写成页面的形式可以通过非父子传值(eventBus)

写一个js

import Vue from 'vue'
var eventBus = new Vue({});
export default eventBus;

父子组件都引入:::::::
子组件

返回上一层:

this.$router.go(-1)
event.$emit("自定义事件",data)

父组件

//父组件监听
eventBus.$on("子组件里面的自定义事件",(data)=>{
	// data= 子组件发过来的数据
	console.log(data)
})

祝愿永远不会报错,copy成功

补充:相机授权的时候可以点击拒绝,拒绝后就不能够在调取了

ZXing 库本身并不直接提供重新获取权限的专用 API。通常,JavaScript 库是无法直接在用户拒绝权限后重新触发权限请求的。

在网页开发中,一旦用户拒绝了权限请求,通常最佳的做法是引导用户手动开启权限。用户可以通过浏览器设置或者在地址栏的网站信息中找到相关权限设置,然后重新授权。

调用原生的相机监听方法:
调起相机之前先看一下用户有没有授权,如果没有授权就让他重新进入页面进行授权

	navigator.mediaDevices.getUserMedia({ video: true })
      .then(stream => {
        // 用户授权了相机权限,可以进行后续操作
        console.log('相机已授权')
      })
      .catch(err => {
        // 处理错误,可能是因为权限被拒绝
        console.log('获取相机权限失败:', err);
      });```

评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值