H5 realiza la función de escanear el código QR para leer el código de barras (código QR + código de barras)

Este artículo presenta principalmente el principio de realización de código bidimensional.

1. Usa complementos

npm instalar @zxing/library

2. El constructor de BrowserMultiFormatReader se usa principalmente para abrir la cámara

import { BrowserMultiFormatReader } from "@zxing/library";
  1. vista
<template>
  <div class="pageScan">
    <!-- <van-uploader :after-read="afterRead">
      <div class="item">相册</div>
    </van-uploader> -->
    <span class="fileinput-button">
      <span>相册</span>
      <input type="file" @change="fileChange" id="avatar" accept="image/*" />
    </span>
    <video ref="video" id="video" class="scanVideo" autoplay></video>
    <div class="scanner">
      <div class="box">
        <div class="line"></div>
        <div class="angle"></div>
      </div>
    </div>
  </div>
</template>
  1. Código central (tome vue3 como ejemplo)
<script setup>
import { defineComponent, reactive, onUnmounted, ref } from "vue";
import { useRouter } from "vue-router";
import { BrowserMultiFormatReader } from "@zxing/library";
import QrCode from "qrcode-decoder";
const form = reactive({
  loadingShow: false,
  scanText: "",
  vin: null,
  tipMsg: "尝试识别中...",
  tipShow: false,
});
const result = ref("");
const router = useRouter();

const codeReader = new BrowserMultiFormatReader();
const afterRead = (file) => {
  getUrl(file.file);
};
const fileChange = () => {
  // 获取dom 对象
  let file = document.getElementById("avatar");
  let resultFile = file?.files[0];
  console.log("resultFile", resultFile);
  getUrl(resultFile);
  // let reader = new FileReader();
  // reader.readAsText(resultFile, "UTF-8");
  // console.log("reader", reader);
};
const getUrl = (file) => {
  let qr = new QrCode();
  let url = getObjectURL(file);
  qr.decodeFromImage(url).then((res) => {
    //打印结果为 解析出来的 二维码地址
    // alert(`res.data ${res.data}`);
    if (res.data) {
      router.push({
        path: "/TransferAccout",
        query: { codeResult: res.data },
      });
    }
    // alert(`res.data====${res.data}`, res.data);
  });
};
const getObjectURL = (file) => {
  let url = null;
  if (window.createObjectURL !== undefined) {
    // basic
    url = window.createObjectURL(file);
  } else if (window.URL !== undefined) {
    // mozilla(firefox)
    url = window.URL.createObjectURL(file);
  } else if (window.webkitURL !== undefined) {
    // webkit or chrome
    url = window.webkitURL.createObjectURL(file);
  }
  return url;
};
const openScan = async () => {
  codeReader
    .getVideoInputDevices()
    .then((videoInputDevices) => {
      form.tipShow = true;
      form.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;
        }
      }
      decodeFromInputVideoFunc(firstDeviceId);
    })
    .catch((err) => {
      form.tipShow = false;
      // console.log(`失败出错: ${err}`);
    });
};
openScan();

const decodeFromInputVideoFunc = (firstDeviceId) => {
  codeReader.reset(); // 重置
  form.scanText = "";
  codeReader.decodeFromInputVideoDeviceContinuously(
    firstDeviceId,
    "video",
    (result, err) => {
      form.tipMsg = "正在尝试识别...";
      form.scanText = "";
      if (result) {
        console.log("扫描结果", result);
        result.value = result;
        // alert(`扫描结果${result.value}`);
        router.push({
          path: "/TransferAccout",
          query: { codeResult: result.value },
        });
        // form.scanText = result.text;
        form.scanText = result.getText();
        // alert(`form.scanText===${form.scanText}`);
        if (form.scanText) {
          form.tipShow = false;
        }
      }
      if (err && !err) {
        form.tipMsg = "识别失败";
        setTimeout(() => {
          form.tipShow = false;
        }, 2000);
        // console.error(err);
        // alert("err", err);
      }
    }
  );
};

//销毁组件
onUnmounted(() => {
  codeReader.reset();
  console.log("销毁组件");
});
</script>
  1. Estilo de código QR
// 扫码组件
.scan-index-bar {
  background-image: linear-gradient(-45deg, #42a5ff, #59cfff);
}
.van-nav-bar__title {
  color: #fff !important;
}
.scanVideo {
  height: 80vh;
}
.scanTip {
  width: 100vw;
  text-align: center;
  margin-bottom: 10vh;
  color: white;
  font-size: 4vw;
}
.pageScan {
  overflow-y: hidden;
  background-color: #363636;
  width: 100vw;
  height: 100vh;
  position: relative;
  // :deep(.van-uploader) {
  //   z-index: 99;
  // }
  .item {
    display: inline-block;
    position: absolute;
    right: 10px;
    color: white;
    top: 10px;
    font-size: 16px;
    z-index: 99;
  }
}

.scanner {
  background-size: 3rem 3rem;
  background-position: -1rem -1rem;
  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);
}
.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);
}
.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;
}
.scanner .box:after,
.scanner .box:before,
.scanner .angle:after,
.scanner .angle:before {
  content: "";
  display: block;
  position: absolute;
  width: 3vw;
  height: 3vw;
  border: 0.2rem solid transparent;
}
.scanner .box:after,
.scanner .box:before {
  top: 0;
  border-top-color: #00ff33;
}
.scanner .angle:after,
.scanner .angle:before {
  bottom: 0;
  border-bottom-color: #00ff33;
}
.scanner .box:before,
.scanner .angle:before {
  left: 0;
  border-left-color: #00ff33;
}
.scanner .box:after,
.scanner .angle:after {
  right: 0;
  border-right-color: #00ff33;
}
@keyframes radar-beam {
  0% {
    transform: translateY(-100%);
  }
  100% {
    transform: translateY(0);
  }
}

.result {
  position: fixed;
  top: 20px;
  left: 20px;
  width: 50px;
  height: 50px;
  border-radius: 100%;
  background-color: rgba(0, 0, 0, 0.3);
  z-index: 999;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #fff;
}
.fileinput-button {
  position: absolute;
  display: inline-block;
}

.fileinput-button input {
  position: absolute;
  right: 0px;
  top: 0px;
  opacity: 0;
}
.fileinput-button {
  span {
    font-size: 16px;
  }
  position: absolute;
  display: inline-block;
  overflow: hidden;
  z-index: 99;
  color: white;
  right: 8px;
  top: 8px;
  display: flex;
  align-items: center;
}

``

Supongo que te gusta

Origin blog.csdn.net/weixin_45664217/article/details/129974881
Recomendado
Clasificación