当前位置:   article > 正文

vue H5实现二维码扫一扫_h5 扫一扫

h5 扫一扫

**

一、使用 vue-qrcode-reader

**
1.cnpm install --save vue-qrcode-reader
2.新建扫一扫组件,代码如下:

<template>
  <div class="scan">
    <qrcode-stream
      :camera="camera"
      @decode="onDecode"
      @init="onInit"
      style="height: 100vh"
    >
      <div>
        <div class="qr-scanner">
          <div class="box">
            <div class="line"></div>
            <div class="angle"></div>
          </div>
        </div>
      </div>
    </qrcode-stream>
  </div>
</template>
<script>
// 下载插件
// cnpm install --save  vue-qrcode-reader
// 引入
import { QrcodeStream } from "vue-qrcode-reader";
export default {
  // 注册
  components: { QrcodeStream },
  data() {
    return {
      camera: "auto",
      result: "", // 扫码结果信息
      error: "", // 错误信息
      scancode: true,
    };
  },
  created() {
    this.clickCode();
  },
  methods: {
    clickCode() {
      this.scancode = true;
    },
    //回调扫描结果
    onDecode(result) {
      if (result !== "") {
        this.scancode = false;
        this.$emit("ok", result);
      }
    },
    // 检查是否调用摄像头
    async onInit(promise) {
      try {
        await promise;
      } catch (error) {
        // console.log()
        this.$toast(error.name);
        if (error.name === "NotAllowedError") {
          this.error = "ERROR: 您需要授予相机访问权限";
        } else if (error.name === "NotFoundError") {
          this.error = "ERROR: 这个设备上没有摄像头";
        } else if (error.name === "NotSupportedError") {
          this.error = "ERROR: 所需的安全上下文(HTTPS、本地主机)";
        } else if (error.name === "NotReadableError") {
          this.error = "ERROR: 相机被占用";
        } else if (error.name === "OverconstrainedError") {
          this.error = "ERROR: 安装摄像头不合适";
        } else if (error.name === "StreamApiNotSupportedError") {
          this.error = "ERROR: 此浏览器不支持流API";
        } else if (error.name === "InsecureContextError") {
          this.error =
            "ERROR: 仅允许在安全上下文中访问摄像机。使用HTTPS或本地主机,而不是HTTP。";
        } else {
          this.error = "ERROR:摄像机错误";
        }

        this.$emit("err", this.error);
      }
    },
  },
};
</script>
<style scoped>
.error {
  font-weight: bold;
  color: red;
}
</style>
<style scoped>
.scan {
  width: 100vw;
  border-color: #585858;
  position: fixed;
  top: 0;
  left: 0;
}
.qrcode-stream-camera {
  width: 100%;
  height: 100%;
  display: block;
  -o-object-fit: cover;
  object-fit: cover;
  position: absolute;
  top: 0%;
  left: 0%;
}
.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%; */
  height: 100vh;
  position: relative;
  /* background-color: #1110;*/

  /* background-color: #111; */
}

.qr-scanner .box {
  width: 213px;
  height: 213px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  overflow: hidden;
  border: 0.1rem solid rgba(0, 255, 51, 0.2);
  /* background: url('http://resource.beige.world/imgs/gongconghao.png') no-repeat center center; */
}

.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>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212

3.使用组件

<template>
	<div class="sys">
		<van-nav-bar @click-left="onClickLeft" :safe-area-inset-top="true" title="扫一扫" left-arrow :placeholder="true"
			:fixed="true"></van-nav-bar>
		<BarScan @ok="getResult" @err="geterror" ></BarScan>
	</div>
</template>
 
<script>
    import { setStore } from "@/utils/storage";
	import BarScan from './qrcode.vue'
	export default {
		components:{
			BarScan
		},
		data() {
			return {
				result:''
			}
		},
		created() {
		},
		methods:{
			onClickLeft(){
				this.$router.go(-1);
			},
			getResult(result){
                this.result=result;
                setStore('scanCodeVal', this.result);
                console.log(this.result,'this.result')
                setTimeout(()=>{
                    this.$router.go(-1);
                },600)
			},
			geterror(e){
				this.scancode=false;
				this.$toast(e)
			},
        },
        destroyed(){

        }
	}
</script>
 
<style>
	.sys{
		width: 100vw;
		height: 100vh;
		background: #111;
	}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

注意:1.该扫一扫在IOS16.3及其以上的微信环境会存在兼容性问题,摄像头不聚焦,暂无好的解决方案;
2.如需微信环境可以用第二种方案,如下

**

二、使用html5-qrcode

**
1.cnpm install --save html5-qrcode
2.创建组件,代码如下:

<template>
  <div class="qrcode">
    <div id="reader"></div>
  </div>
</template>

<script>
import { Html5Qrcode } from "html5-qrcode";
export default {
  created() {
    this.getCameras();
  },
  beforeDestroy() {
    this.stop();
  },
  methods: {
    getCameras() {
      Html5Qrcode.getCameras()
        .then((devices) => {
          if (devices && devices.length) {
            this.html5QrCode = new Html5Qrcode("reader");
            this.start();
          }
        })
        .catch((err) => {
          // handle err
          this.html5QrCode = new Html5Qrcode("reader");
          this.error = "ERROR: 您需要授予相机访问权限";
          this.$emit("err", this.error);
        });
    },
    start() {
      //environment后置 user前置
      this.html5QrCode
        .start(
          { facingMode: "environment" },
          {
            fps: 2,
            qrbox: { width: 250, height: 250 },
          },
          (decodedText, decodedResult) => {
            this.$emit("ok", decodedText);
          }
        )
        .catch((err) => {
          this.$emit("err", err);
        });
    },
    stop() {
      this.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.");
        });
    },
  },
};
</script>

<style lang="less" scoped>
.qrcode {
  position: relative;
  height: 100%;
  width: 100%;
  background:#000000;
  opacity: 0.48;
}
#reader {
  top: 50%;
  left: 0;
  transform: translateY(-50%);
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

3.引入组件:

<template>
	<div class="sys">
		<!-- <van-nav-bar @click-left="onClickLeft" :safe-area-inset-top="true" title="扫一扫" left-arrow :placeholder="true"
			:fixed="true"></van-nav-bar> -->
		<BarScan ref="qrcode" @ok="getResult" @err="geterror" ></BarScan>
	</div>
</template>
 
<script>
    import { setStore } from "@/utils/storage";
	import BarScan from './qrCodeHtml.vue'
	export default {
		components:{
			BarScan
		},
		data() {
			return {
				result:''
			}
		},
		created() {
		},
		methods:{
			onClickLeft(){
				this.$router.back();
			},
			getResult(result){
                this.result = result;
                setStore('scanCodeVal', this.result);
                setTimeout(()=>{
                    this.$router.back();
                },600)
			},
			geterror(e){
				this.scancode=false;
				this.$toast(e)
			},
        },
        destroyed(){

        }
	}
</script>
 
<style lang="less" scoped>
	.sys{
		width: 100vw;
		height: 100vh;
		background: #111;
		overflow: hidden;
	}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/859646
推荐阅读
相关标签
  

闽ICP备14008679号