qrcodeScan.vue
<template>
<div class="scan-wrap">
<div class="close" @click="$emit('scanCancel')">
<svg t="1684381277846" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2270" width="200" height="200">
<path d="M305.792 508.288a31.872 31.872 0 0 1 9.28-19.84l361.984-362.112a32 32 0 0 1 45.312 45.248L381.248 512.64l341.12 340.992a32 32 0 1 1-45.312 45.248L315.072 536.96a31.872 31.872 0 0 1-9.28-19.904z"
fill="#fff"></path>
</svg>
</div>
<div id="qr-reader" style="width:100%;height: 100%;"></div>
<div class="file-box">
相册<input ref="qr-input-file" type="file" accept="image/*">
</div>
</div>
</template>
<script>
import { Html5Qrcode } from "html5-qrcode";
export default {
data() {
return {
qrcode: null
}
},
mounted() {
this.scanCamera();
this.scanFile();
},
methods: {
scanCamera() {
let html5QrCode = new Html5Qrcode("qr-reader");
this.qrcode = html5QrCode
html5QrCode.start({
facingMode: {
exact: "environment"
}
}, {
fps: 40,
qrbox: { width: 250, height: 250 },
aspectRatio: 1.9
}, (decodedText, decodedResult) => {
this.$emit('scanSuccess', decodedText)
}, (err) => {
}).catch((err) => {
this.$emit('scanCancel', err)
});;
},
scanFile() {
const fileinput = this.$refs['qr-input-file'];
fileinput.addEventListener('change', e => {
if (e.target.files.length == 0) {
return;
}
const imageFile = e.target.files[0];
let html5QrCode = new Html5Qrcode("qr-reader");
html5QrCode.scanFile(imageFile, true)
.then(decodedText => {
this.$emit('scanSuccess', decodedText)
})
.catch(err => {
this.$emit('scanError', err)
});
});
}
},
beforeDestroy() {
this.qrcode.stop()
},
props: {
value: {
type: Boolean,
default: false
}
}
}
</script>
<style scoped lang="scss">
.scan-wrap {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #fff;
z-index: 999999;
}
#qr-reader {
box-sizing: border-box;
}
.close {
position: absolute;
left: .5rem;
top: .7rem;
width: .7rem;
height: .7rem;
line-height: .7rem;
border-radius: 50%;
text-align: center;
background-color: rgba(0, 0, 0, .5);
padding: .1rem;
z-index: 99;
svg {
width: 100%;
height: 100%;
}
}
.file-box {
position: absolute;
right: .5rem;
bottom: .7rem;
width: 1.2rem;
height: 1.2rem;
line-height: 1.2rem;
border-radius: 50%;
text-align: center;
background-color: rgba(0, 0, 0, .8);
color: #fff;
font-size: .28rem;
z-index: 99;
}
.file-box input {
width: 100%;
height: 100%;
opacity: 0;
position: absolute;
top: 0;
left: 0;
}
</style>
使用方法
<template>
<div class="warp">
<div class="box" @click="scanDalog=true">打开摄像头</div>
<v-qrcodeScan v-if="scanDalog" @scanCancel="scanCancel" @scanSuccess="scanSuccess" @scanError="scanError"></v-qrcodeScan>
</div>
</template>
<script>
export default {
data() {
return {
scanDalog:false,
}
},
computed: {},
methods: {
scanCancel(err){
if(err){
alert('用户取消授权,关闭弹框!')
}
this.scanDalog=false
},
scanError(err){
alert('识别二维码错误')
},
scanSuccess(e){
alert(e)
}
},
}
</script>