发布时间:2023-05-30 文章分类:WEB开发, 电脑百科 投稿人:李佳 字号: 默认 | | 超大 打印

js实现web页面扫描二维码(html5-qrcode)

以vue3项目使用为例
这种还是推荐IOS和安卓原生实现,做桥接文件调用
这种实现方式只支持localhost和https的浏览器网页版
而且经过测试兼容性也不是很好,具体参见官网
下面附了官网链接

1.下载依赖

npm install html5-qrcode

2.二次封装

<template>
  <div>
    <div class="readerDialog" v-show="dialogShow">
      <div id="reader" width="600px"></div>
    </div>
  </div>
</template>
<script>
// 调起摄像头扫描二维码
import { ref, reactive, toRefs, watch, getCurrentInstance } from 'vue';
import { Html5Qrcode } from 'html5-qrcode';
export default {
  name: 'Qrcode',
  props: [],
  emits: ['success'],
  setup (props, { emit }) {
    const params = reactive({
      dialogShow: false,
      codeUrl: '',
      cameraId: '',
      showText: '',
      devices: [],
      getCamerasText: '',
      html5QrCode: null
    });
    // 外部调用此方法打开
    const open = () => {
      params.dialogShow = true;
      console.log('params.dialogShow', params.dialogShow);
      getCameras();
    };
    const getCameras = () => {
      params.getCamerasText = JSON.stringify(Html5Qrcode.getCameras());
      Html5Qrcode.getCameras()
        .then((devices) => {
          params.showText = JSON.stringify(devices);
          /**
           * devices would be an array of objects of type:
           * { id: "id", label: "label" }
           */
          if (devices && devices.length) {
            // 如果有2个摄像头,1为前置的
            if (devices.length > 1) {
              params.cameraId = devices[1].id;
            } else {
              params.cameraId = devices[0].id;
            }
            params.devices = devices;
            start();
            // .. use this to start scanning.
          }
        })
        .catch((err) => {
          params.showText = err;
          console.log('getCameras err:', err); // 获取设备信息失败
        });
    };
    const start = () => {
      params.html5QrCode = new Html5Qrcode('reader');
      params.html5QrCode.start(
        params.cameraId, // retreived in the previous step.
        {
          fps: 10, // sets the framerate to 10 frame per second
          qrbox: { width: 250, height: 250 }, // sets only 250 X 250 region of viewfinder to
          // scannable, rest shaded.
        },
        (decodedText, decodedResult) => {
          // do something when code is read. For example:
          // if (qrCodeMessage) {
          //   this.getCode(qrCodeMessage);
          //   this.stop();
          // }
          console.log('===成功日志:', decodedText);
          console.log(typeof decodedResult, decodedResult);
          emit('success', decodedText);
          stop();
          params.dialogShow = false;
        },
        (errorMessage) => {
          // parse error, ideally ignore it. For example:
          // console.log(`QR Code no longer in front of camera.`);
          console.log('非扫描成功日志:', errorMessage);
        }
      )
        .catch((err) => {
          // Start failed, handle it. For example,
          console.log(`Unable to start scanning, error: ${err}`);
        });
    };
    const stop = () => {
      params.html5QrCode
        .stop()
        .then((ignore) => {
          // QR Code scanning is stopped.
          console.log('QR Code scanning stopped.');
        })
        .catch((err) => {
          // Stop failed, handle it.
          console.log('Unable to stop scanning.');
        });
    };
    return {
      ...toRefs(params),
      getCameras,
      open
    };
  },
};
</script>
<style lang="scss" scoped>
.readerDialog {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 999999;
  background: #333;
  #reader {
    top: 25%;
  }
}
</style>

3.使用(以下只演示部分核心代码)

html部分

<van-button type="success" @click="cameraClick">开始扫描</van-button>
<Qrcode ref="QrcodeRef" @success="qrcodeSuccess" />

js部分

import Qrcode from '@/components/Qrcode/index.vue';
const QrcodeRef = ref();
const qrcodeText = ref('');
// 扫描调起
const cameraClick = () => {
  QrcodeRef.value.open();
};
// 扫描成功回调
const qrcodeSuccess = (txt) => {
  qrcodeText.value = txt;
};

官网:https://github.com/mebjas/html5-qrcode