vue实现生成二维码与扫描二维码

步博厚
2023-12-01

生成二维码:

<template>
    <div class="QRCode" :style="{'width':width, 'height':height}">
      <canvas :id="canvasId" :style="{'width':width, 'height':height}"></canvas>
      <!-- <div class="QQMode" v-if="load || view"><a-icon type="download" @click="loadCode" v-if="load" /></div> -->
    </div>
  </template>
  <script>
  import QRCode from "qrcode";
  export default {
    name: "myqrcode",
    props: {
      content: {
        type: String,
        default: "二维码信息数据"
      },
      width: {
        type: String,
        default: "100"
      },
      height: {
        type: String,
        default: "100"
      },
      codeName: {
        type: String,
        default: "二维码"
      },
      load: {
        type: Boolean,
        default: true
      },
      view: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        canvasId: ""
      };
    },
    computed: {},
    created() {
      this.canvasId = this.getUUID();
      this.$nextTick(() => {
        this.init();
      });
    },
    mounted: function() {},
    methods: {
      init() {
        let width = this.width,
          height = this.height;
        QRCode.toCanvas(
          document.getElementById(this.canvasId),
          this.content,
          { width, height, toSJISFunc: QRCode.toSJIS },
          error => {}
        );
      },
      getUUID() {
        let d = new Date().getTime();
        let uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
          /[xy]/g,
          function(c) {
            let r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c == "x" ? r : (r & 0x7) | 0x8).toString(16);
          }
        );
        return uuid;
      }
      //下载二维码
      // loadCode() {
      //   let [F, S, a] = [
      //     navigator.userAgent.indexOf("Firefox") > -1,
      //     document.getElementById(this.canvasId).toDataURL("image/png"),
      //     document.createElement("a")
      //   ];
      //   // var dataurl = showel.toDataURL();
      //   var arr = S.split(","),
      //     mime = arr[0].match(/:(.*?);/)[1],
      //     bstr = atob(arr[1]),
      //     n = bstr.length,
      //     u8arr = new Uint8Array(n);
      //   while (n--) {
      //     u8arr[n] = bstr.charCodeAt(n);
      //   }
      //   var file = new File([u8arr], this.codeName + ".png", { type: mime });
      //   $A.FU(file, data => {
      //     // alert(1)
      //     // window.location.href = data;
      //     [a.href, a.download] = [data, this.codeName];
      //     // a.download = '二维码';
      //     if (F) {
      //       let evt = document.createEvent("MouseEvents");
      //       evt.initEvent("click", true, true);
      //       a.dispatchEvent(evt);
      //     } else {
      //       a.click();
      //     }
      //   });
      // },
      // insertContentLoad(content, size) {
      //   const ele = document.createElement("canvas");
      //   ele.style.width = size.width || "100" + "px";
      //   ele.style.height = size.height || "100" + "px";
      //   QRCode.toCanvas(
      //     ele,
      //     content,
      //     {
      //       width: size.width || "100",
      //       height: size.height || "100",
      //       toSJISFunc: QRCode.toSJIS
      //     },
      //     error => {}
      //   );
      //   let [F, S, a] = [
      //     navigator.userAgent.indexOf("Firefox") > -1,
      //     ele.toDataURL("image/png"),
      //     document.createElement("a")
      //   ];
      //   [a.href, a.download] = [S, size.name];
      //   // a.download = '二维码';
      //   if (F) {
      //     let evt = document.createEvent("MouseEvents");
      //     evt.initEvent("click", true, true);
      //     a.dispatchEvent(evt);
      //   } else {
      //     a.click();
      //   }
      // }
    },
    watch: {
      content(val) {
        this.init();
      }
    }
  };
  </script>
  <style scoped>
  .QRCode {
    display: inline-block;
    position: relative;
    overflow: hidden;
  }
  .QQMode {
      position: absolute;
      left: 0;
      bottom: 100%;
      right: 0;
      height: 0;
      background-color: rgba(0, 0, 0, 0.45);
      transition: all 200ms ease-in-out;
      cursor: pointer;
      color: #fff;
      display: flex;
      justify-content: space-around;
      align-items: center;
      font-size: 20px;
      font-weight: bolder;
      box-sizing: border-box;
      padding: 10px;
    }
  .QRCode:hover .QQMode {
    bottom: 0;
    height: 100%;
  }
  </style>

扫描二维码

<template>
    <div>
      <div class="qrcodebox fixcenter">   
        <qrcode-stream 
              :camera="camera"
               @decode="onDecode" 
               @init="onInit">
              <div class="qr-scanner">
                  <div class="box">
                      <div class="line"></div>
                      <div class="angle"></div>
                  </div>
                  <div class="txt">
                      扫描二维码
                  </div>
              </div>
        </qrcode-stream>
      </div>
    </div>
  </template>
  
  <script>
  import { QrcodeStream } from 'vue-qrcode-reader'
  
  export default {
  
    components: { QrcodeStream },
  
    data () {
      return {
        camera: 'auto',
        result: null,
      }
    },
  
    computed: {
    },
  
    methods: {
      onInit (promise) {
        promise
          .catch(console.error)
          .then(() => {
            console.log('扫描初始化完成')
          })
      },
  
      async onDecode (content) {
        this.result = content;
        this.turnCameraOff();
      },
  
      timeout (ms) {
        return new Promise(resolve => {
          window.setTimeout(resolve, ms)
        })
      },
      turnCameraOn () {
        this.camera = 'auto'
      },

      turnCameraOff () {
        this.camera = 'off'
      },
    }
  }
  </script>
  
  <style scoped>
    .qrcodebox{
      width: 10rem;
      height: 10rem;
    }
    .qr-scanner {
        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;
      width: 100%;
      height: 100%;
      position: relative;
      background-color: #1110;
    }
    .qr-scanner .box {
      width: 10rem;
      height: 10rem;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      overflow: hidden;
      border: 0.03rem solid rgba(0, 255, 51, 0.2);
      /* background: url('http://resource.beige.world/imgs/gongconghao.png') no-repeat center center; */
    }
    .qr-scanner .txt {
      width: 100%;
      height: 1rem;
      line-height: 1rem;
      font-size: 0.6rem;
      text-align: center;
      /* color: #f9f9f9; */
      margin: 0 auto;
      position: absolute;
      top: 110%;
      left: 0;
    }
    .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);
      }
    }
  </style>

 类似资料: