10 changed files with 727 additions and 7 deletions
@ -0,0 +1,165 @@ |
|||||
|
<template> |
||||
|
<div class="scanCode"> |
||||
|
<div class="container"> |
||||
|
<div class="qrcode"> |
||||
|
<div id="reader"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="btn"> |
||||
|
<div class="left-back"> |
||||
|
<van-icon name="arrow-left" @click="clickBack" /> |
||||
|
</div> |
||||
|
<div class="right-file"> |
||||
|
<van-uploader |
||||
|
v-model="fileList" |
||||
|
:preview-image="false" |
||||
|
:after-read="dealSelectFiles" |
||||
|
> |
||||
|
<van-icon name="photo-o" |
||||
|
/></van-uploader> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { reactive } from "vue"; |
||||
|
import { defineComponent, toRefs, onMounted, onUnmounted } from "vue"; |
||||
|
import { Html5Qrcode } from "html5-qrcode"; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
setup() { |
||||
|
const state = reactive({ |
||||
|
html5QrCode: null, |
||||
|
fileList: [], |
||||
|
}); |
||||
|
const start = () => { |
||||
|
state.html5QrCode |
||||
|
.start( |
||||
|
{ facingMode: "environment" }, |
||||
|
{ |
||||
|
fps: 1, |
||||
|
qrbox: { width: 250, height: 250 }, |
||||
|
}, |
||||
|
(decodedText, decodedResult) => { |
||||
|
console.log("decodedText", decodedText); |
||||
|
console.log("decodedResult", decodedResult); |
||||
|
} |
||||
|
) |
||||
|
.catch((err) => { |
||||
|
console.log("扫码错误信息", err); |
||||
|
let message = ""; // 错误信息处理仅供参考,具体描述自定义 |
||||
|
if (typeof err == "string") { |
||||
|
message = "二维码识别失败!"; |
||||
|
} else { |
||||
|
if (err.name == "NotAllowedError") { |
||||
|
message = "您需要授予相机访问权限!"; |
||||
|
} |
||||
|
if (err.name == "NotFoundError") { |
||||
|
message = "这个设备上没有摄像头!"; |
||||
|
} |
||||
|
if (err.name == "NotSupportedError") { |
||||
|
message = |
||||
|
"摄像头访问只支持在安全的上下文中,如https或localhost!"; |
||||
|
} |
||||
|
if (err.name == "NotReadableError") { |
||||
|
message = "相机被占用!"; |
||||
|
} |
||||
|
if (err.name == "OverconstrainedError") { |
||||
|
message = "安装摄像头不合适!"; |
||||
|
} |
||||
|
if (err.name == "StreamApiNotSupportedError") { |
||||
|
message = "此浏览器不支持流API!"; |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
const getCameras = () => { |
||||
|
Html5Qrcode.getCameras() |
||||
|
.then((devices) => { |
||||
|
if (devices && devices.length) { |
||||
|
state.html5QrCode = new Html5Qrcode("reader"); |
||||
|
start(); |
||||
|
} |
||||
|
}) |
||||
|
.catch((err) => { |
||||
|
alert("摄像头无访问权限!"); |
||||
|
}); |
||||
|
}; |
||||
|
const stop = () => { |
||||
|
state.html5QrCode |
||||
|
.stop() |
||||
|
.then((ignore) => { |
||||
|
console.log("停止扫码", ignore); |
||||
|
}) |
||||
|
.catch((err) => { |
||||
|
console.log(err); |
||||
|
alert("停止扫码失败"); |
||||
|
}); |
||||
|
}; |
||||
|
const dealSelectFiles = () => { |
||||
|
try { |
||||
|
window.qrcode.callback = (result) => { |
||||
|
alert("成功了,结果是:" + result); |
||||
|
}; // get select files. |
||||
|
let file = state.fileList[0].file; |
||||
|
var reader = new FileReader(); |
||||
|
reader.onload = (function () { |
||||
|
return function (e) { |
||||
|
window.qrcode.decode(e.target.result); |
||||
|
}; |
||||
|
})(file); |
||||
|
reader.readAsDataURL(file); |
||||
|
} catch (error) { |
||||
|
alert("图片识别失败!"); |
||||
|
} |
||||
|
}; |
||||
|
onMounted(() => { |
||||
|
getCameras(); |
||||
|
}); |
||||
|
onUnmounted(() => { |
||||
|
//扫描设备是否在运行 |
||||
|
if (state.html5QrCode.isScanning) { |
||||
|
stop(); |
||||
|
} |
||||
|
}); |
||||
|
return { |
||||
|
...toRefs(state), |
||||
|
getCameras, |
||||
|
dealSelectFiles, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.scanCode { |
||||
|
height: 100vh; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
background: rgba(0, 0, 0); |
||||
|
} |
||||
|
.container { |
||||
|
height: 90vh; |
||||
|
position: relative; |
||||
|
width: 100%; |
||||
|
} |
||||
|
.qrcode { |
||||
|
height: 100%; |
||||
|
} |
||||
|
#reader { |
||||
|
top: 50%; |
||||
|
left: 0; |
||||
|
transform: translateY(-50%); |
||||
|
} |
||||
|
.btn { |
||||
|
flex: 1; |
||||
|
padding: 3vw; |
||||
|
display: flex; |
||||
|
justify-content: space-around; |
||||
|
color: #fff; |
||||
|
font-size: 8vw; |
||||
|
align-items: flex-start; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
Loading…
Reference in new issue