H5页面如何实现扫码功能?uniapp如何兼容H5扫码功能?
作者:程序员11 时间:2023-05-18 人气:447 QQ交流群\邮箱:1003265987@qq.com
H5页面如何实现扫码功能?uniapp如何兼容H5扫码功能?
要展示的内容
本文主要使用html5-qrcode
库实现二维码扫描功能,官方github地址:github.com/mebjas/html…
引入html5-qrcode
npm i html5-qrcode
或者:
<script src="https://unpkg.com/html5-qrcode" type="text/javascript">
注意事项:
浏览器需要在
https
或者localhost
下才能调用相机,关于本地调试如何启用https参考# 如何在本地启用https服务?浏览器需要开启相机使用权限
基本使用
实例化html5-qrcode
<div id="reader"></div><script> // reader是DOM的id var html5QrCode = new Html5Qrcode("reader")</script>
识别文件夹中的二维码图片
// 返回promise对象,imageFile,file对象,第二个参数:是否将图片显示到画布上html5QrCode.scanFile(imageFile, true) .then(qr => { console.log(qr) // 二维码结果 }) .catch(err => { console.log(err) })
扫码,利用相机进行扫码
// 获取相机设备Html5Qrcode.getCameras() .then(devices => { // 扫码配置 const config = { fps: 10, // 二维码扫描每秒帧数 qrbox: { width: 300, height: 300 }, // UI框的大小 aspectRatio: 1.777778, // 纵横比,此值表示全屏 } if (devices && devices.length) { const cameraId = devices[devices.length - 1].id //后置摄像头,一般最后一个是后置摄像头 //let cameraId = devices[0].id //前置摄像头 // 打开相机,开始扫描,callbackSuccess, callbackFailure扫描成功与失败的回调函数(自行定义) html5QrCode.start({ deviceId: { exact: cameraId } }, config, callbackSuccess, callbackFailure).catch(err => { alert(err) }) } else { // 如果没有找到设备,直接启用摄像头 //environment:后置摄像头 user:前置摄像头 html5QrCode.start({ facingMode: "environment" }, config, onScanSuccess, onScanFailure).catch(err => { alert(err) }) } }) .catch(err => { alert(err) })
停止扫描
html5QrCode.stop()
清除画布
html5QrCode.clear()
vue中开发扫码页面
本次demo使用的是vue3,参考大多数扫码功能,都是以页面的形式展示,也可以封装为组件,主要看项目需求
思路:
点击扫描,跳转扫一扫页面,打开相机扫码
识别成功放回上一页,并将结果传递给上一页
实现效果:
主要实现代码:
demo源码:github.com/Abner105/sc…
ScanView.vue 扫码页面
主要实现调起相机扫码,并返回结果到上一个页面
<template> <div> <div @click="close" class="title">扫码 X</div> <!-- 扫描仪占位符 --> <div id="reader"></div> </div></template><script setup>import { Html5Qrcode } from "html5-qrcode"import { onMounted } from "vue"import { useRouter } from "vue-router"import { onBeforeRouteLeave } from "vue-router"const router = useRouter()let html5QrCode = nullconst scanRes = {} // 存放扫码结果// 路由导航,将扫码结果放回给上一页onBeforeRouteLeave(to => { to.query.scanRes = scanRes})// 关闭扫码页面const close = () => { html5QrCode.stop().finally(() => { html5QrCode.clear() router.back() })}// // 扫码成功的回调const onScanSuccess = qr => { scanRes.qr = qr close()}// 使用相机扫码const useCamera = () => { // 实例化,接收元素id作为参数 html5QrCode = new Html5Qrcode("reader") // 获取相机设备 Html5Qrcode.getCameras() .then(devices => { // 扫码配置 const config = { fps: 10, // 二维码扫描每秒帧数 qrbox: { width: 300, height: 300 }, // UI框的大小 aspectRatio: 1.777778, showTorchButtonIfSupported: true, } if (devices && devices.length) { let cameraId = devices[devices.length - 1].id //后置摄像头,一般最后一个是后置摄像头 //let cameraId = devices[0].id //前置摄像头 html5QrCode.start({ deviceId: { exact: cameraId } }, config, onScanSuccess).catch(err => { scanRes.err = err router.back() }) } else { // 如果没有找到设备,直接启用摄像头 //environment:后置摄像头 user:前置摄像头 html5QrCode.start({ facingMode: "environment" }, config, onScanSuccess).catch(err => { scanRes.err = err router.back() }) } }) .catch(err => { scanRes.err = err router.back() })}onMounted(() => { useCamera()})</script>
HomeView.vue
调起扫码页面,处理扫码结果
选择二维码图片并识别二维码
<template> <div> <div class="title">Home</div> <button class="button"> <input ref="inputRef" @change="useLocal" type="file" class="upload-input" accept="image/*" /> <span>选择二维码</span> <div id="reader1"></div> </button> <button class="button" @click="useCamera">扫描二维码</button> </div></template><script setup>import { onMounted } from "vue"import { Html5Qrcode } from "html5-qrcode"import { useRouter } from "vue-router"import { useRoute } from "vue-router"const router = useRouter()const route = useRoute()onMounted(() => { // 页面返回时,拿到扫码结果并处理 const { qr, err } = route.query.scanRes || {} if (qr) { alert(qr) // 处理扫码成功结果 } else if (err) { alert(err) // 处理失败结果 }}) // 选取二维码图片并识别const useLocal = e => { if (e.target.files.length == 0) { return } const imageFile = e.target.files[0] const html5QrCode = new Html5Qrcode("reader1") html5QrCode.scanFile(imageFile, false) .then(qr => { alert(qr) }) .catch(err => { alert(err) })}const useCamera = () => { router.push("/scan") // 去扫码页面}</script><style>.title{ height: 50px; line-height: 50px;}button{ height: 50px; width: 120px;}</style>
uniapp中封装扫码页面
uniapp中uni.scanCode()可以调起扫码功能,但该API不兼容H5,因此H5页面还是需要自己写一个扫码页面。整体逻辑还是参考vueH5页面的实现。
demo代码:
当前uniapp项目中二维码图片识别功能使用的是reqrcode.js库,也可以使用html5-qrcode,这里我懒得改了。
pagexxx.vue 扫一扫入口页面
<image src="/static/icon/scan.svg" @click="scancode"></image><script>// #ifdef H5const qrcode = require("@/utils/reqrcode.js") // 用于识别二维码图片// #endifexport default { data() { return { // #ifdef H5 scanResult: {}, // 扫码结果 // #endif } }, onShow() { // #ifdef H5 if (this.scanResult.qr) { this.handleScan(this.scanResult.qr) } else if (this.scanResult.err) { uni.showToast({ title: this.scanResult.err, duration: 2000, icon: "none", }) } this.scanResult = {} // #endif }, methods: { handleScan(address) { // 处理扫码逻辑 }, // 扫描二维码 scancode() { let that = this // #ifdef APP-PLUS // APP使用uni自带的API uni.scanCode({ scanType: ["qrCode"], success: res => { that.handleScan(res.result) }, }) // #endif // #ifdef H5 uni.showActionSheet({ itemList: ['扫描二维码', '选择二维码图片'], success(res) { if (!res.tapIndex) { // 去扫码页面 uni.navigateTo({ url: "/pages/scan/scan", }) } else { // 选择二维码图片 uni.chooseImage({ count: 1, success: function (res) { const tempFilePaths = res.tempFilePaths qrcode.decode(tempFilePaths[0]) qrcode.callback = function (img) { if (img == "error decoding QR Code") { uni.showToast({ title: "Incorrect QR code", duration: 2000, icon: "none", }) } else { that.handleScan(img) } } }, }) } }, }) // #endif } }}</script>
san.vue 扫一扫页面
<template> <view> <!-- uView的自定义导航栏,背景设置为透明 --> <u-navbar :title="$t('common.scan')" @leftClick="closed" :titleStyle="{ fontWeight: '600', color: '#ffffff' }" bgColor="transparent" leftIconColor="#ffffff" ></u-navbar> <!-- 扫描仪占位符 --> <view id="reader"></view> </view></template><script>import { Html5Qrcode } from "html5-qrcode"export default { data() { return { html5QrCode: null, } }, mounted() { this.useCamera() // 打开相机 }, methods: { // 关闭扫一扫页面,返回上一页 closed() { this.html5QrCode.stop().finally(() => { this.html5QrCode.clear() uni.navigateBack() }) }, scanRes(qr, err) { // 修改上一个页面的数据,传递qr var pages = getCurrentPages() var prevPage = pages[pages.length - 2] prevPage.$vm.scanResult = { qr, err } }, // 成功回调 onScanSuccess(qr) { this.scanRes(qr) this.closed() }, useCamera() { // 实例化,接收元素id作为参数 this.html5QrCode = new Html5Qrcode("reader") // 获取相机设备 Html5Qrcode.getCameras() .then(devices => { // 扫码配置 const config = { fps: 10, // 二维码扫描每秒帧数 qrbox: { width: 300, height: 300, }, // UI框的大小 aspectRatio: 1.777778, } if (devices && devices.length) { let cameraId = devices[devices.length - 1].id //后置摄像头,一般最后一个是后置摄像头 //let cameraId = devices[0].id //前置摄像头 this.html5QrCode .start({ deviceId: { exact: cameraId, }, }, config, this.onScanSuccess) .catch(err => { this.scanRes(undefined, err) uni.navigateBack() }) } else { // 如果没有找到设备,直接启用摄像头 //environment:后置摄像头 user:前置摄像头 this.html5QrCode .start( { facingMode: "environment" }, config, this.onScanSuccess ) .catch(err => { this.scanRes(undefined, err) uni.navigateBack() }) } }) .catch(err => { this.scanRes(undefined, err) uni.navigateBack() }) }, },}</script>
温馨提示:
欢迎阅读本文章,觉得有用就多来支持一下,没有能帮到您,还有很多文章,希望有一天能帮到您。
H5页面如何实现扫码功能?uniapp如何兼容H5扫码功能?---相关文章
HTML5-热门文章
活跃用户












