vue实现h5扫码的代码示例
作者:举半个栗子
html5-qrcode是一个基于JavaScript 轻量级和跨平台的扫码插件,允许用户使用摄像头扫描二维码,并且解析为文本或者url,本文给大家介绍了vue实现h5扫码,需要的朋友可以参考下
插件 html5-qrcode npm地址
html5-qrcode是一个基于JavaScript 轻量级和跨平台的扫码插件。允许用户使用摄像头扫描二维码,并且解析为文本或者url。
- 支持扫描不同类型的二维码和条形码
- 支持不同的平台,Android、IOS、Windows、MacOs或者linux
- 支持不同的浏览器,Chrome、Safari、Edge等
- 支持扫描本地文件
访问摄像头涉及用户隐私,所以访问环境必须在https下
实现(该代码环境基于vue3)
- 安装依赖
npm install html5-qrcode
- 引入
import { Html5Qrcode } from 'html5-qrcode'
- 使用
setup数据
const state = reactive({ html5QrCode: null, fileList:[] })
- 判断当前环境下是否有摄像头
Html5Qrcode.getCameras() .then(devices =>{ if(devices &&devices.length){ // 当前环境下能识别出摄像头,并且摄像头的数据可能不止一个 state.html5QrCode = new Html5Qrcode('reader') // reader 放置扫码功能的元素ID startInit() } }) .catch(() =>{ // 摄像头无访问权限 })
- 扫码
const startInit = () =>{ state.html5QrCode.start( // environment后置摄像头 user前置摄像头 {facingMode:'environment'}, { fps:1, // 可选,每n秒帧扫描一次 qrbox:{ width:250, height:250 } // 扫描的 UI框 }, (decodedText, decodedResult) =>{ // 扫描结果 } ) .catch((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 dealSelectFiles = () => { try { window.qrcode.callback = (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) { // 识别失败 } }
- 在离开页面时要停止扫码功能
onUnmounted(() => { //扫描设备是否在运行 if (state.html5QrCode.isScanning) { stop() } })
完整代码
<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' import { showToast, } from 'vant' 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) => { showToast({ message: '摄像头无访问权限!', duration: 3000 }) } const stop = () => { state.html5QrCode .stop() .then((ignore) => { console.log('停止扫码', ignore) }) .catch((err) => { console.log(err) showToast('停止扫码失败') }) } const dealSelectFiles = () => { try { window.qrcode.callback = (result) => { showToast('成功了,结果是:' + 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) { showToast({ message: '图片识别失败!', duration: 3000 }) } } 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>
最终效果
以上就是vue实现h5扫码的代码示例的详细内容,更多关于vue实现h5扫码的资料请关注脚本之家其它相关文章!