Zxing+Vue实现扫码功能

文章描述:

Vue+Zxing实现H5扫码功能,前后摄像头可以切换

template

创建一个video

<template>
  <div class="scan">
    <div class="video-container">
      <video class="video" id="video-1"></video>
    </div>
    <div class="camera-container" v-if="videoInputDevices.length">
      <label>摄像头:</label>
      <select v-model="currentVideoInputDevice">
        <option
          v-for="(videoInputDevice, index) in videoInputDevices"
          :key="index"
          :value="videoInputDevice"
        >
          {{ videoInputDevice.label }}
        </option>
      </select>
    </div>
  </div>
</template>

script

调用摄像头,解码

import { BrowserMultiFormatReader, ChecksumException, FormatException } from "@zxing/library";
export default {
  name: "Scan",
  data() {
    return {
      codeReader: new BrowserMultiFormatReader(),
      videoInputDevices: [],
      currentVideoInputDevice: {},
      decodeResult: undefined,
    };
  },
  methods: {
    async openScan() {
      const _this = this;
      _this.codeReader
        .getVideoInputDevices() //老版本listVideoInputDevices()
        .then((videoInputDevices) => {
          if (videoInputDevices && videoInputDevices.length) {
            if (videoInputDevices.length > 1) {
              videoInputDevices.reverse();
            } //防止先唤出前摄像头
            _this.videoInputDevices = videoInputDevices;
            _this.currentVideoInputDevice = videoInputDevices[0];
          }
        })
        .catch(() => {});
    },

    decodeFromInputVideo() {
      const _this = this;
      _this.codeReader.reset();
      // 多次
      _this.codeReader.decodeFromVideoDevice(
        _this.currentVideoInputDevice.deviceId,
        "video-1",
        (result, err) => {
          if (result) {
            _this.decodeResult = result;
          }
          if (err) {
            if (err instanceof ChecksumException) {
              console.log(
                "A code was found, but it's read value was not valid."
              );
            }
            if (err instanceof FormatException) {
              console.log("A code was found, but it was in a invalid format.");
            }
          }
        }
      );
    },

    successDecode() {
      const _this = this;
      alert(_this.decodeResult.text);
    },
  },
  watch: {
    currentVideoInputDevice: function () {
      this.decodeFromInputVideo();
    },
    decodeResult: function () {
      this.successDecode();
    },
  },
  mounted: function () {
    this.openScan();
  },
  unmounted: function () {
    this.codeReader.reset(); //关闭摄像头
  }
}

style

<style scoped lang="scss">
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
.scan {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #ff9900;
  width: 100vw;
  height: 100vh;
  background: #000;
  .video-container {
    margin-top: 10px;
    display: flex;
    justify-content: center;
    video {
      width: 96vw;
      max-height: 80vh;
    }
    @media (min-width: 500px) {
      video {
        // width: 80vh;
        max-width: 96vw;
        height: 80vh;
      }
    }
  }
  .camera-container {
    margin-top: 5vh;
    width: 80%;
    height: 50px;
    line-height: 44px;
    border-radius: 10px;
    border: 3px solid #ff9900;
    display: flex;
    justify-content: center;
    select {
      width: calc(100% - 80px);
      color: #ff9900;
      background: transparent;
      border: none;
      outline: none;
    }
  }
}
</style>

 

发布时间:2023/01/05

发表评论