ddddd

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

注意事项:

  1. 浏览器需要在https或者localhost下才能调用相机,关于本地调试如何启用https参考# 如何在本地启用https服务?

  2. 浏览器需要开启相机使用权限

基本使用

实例化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,参考大多数扫码功能,都是以页面的形式展示,也可以封装为组件,主要看项目需求

思路:

  1. 点击扫描,跳转扫一扫页面,打开相机扫码

  2. 识别成功放回上一页,并将结果传递给上一页

实现效果:

主要实现代码:

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>

链接:https://juejin.cn/post/7216559027513442359

温馨提示:

欢迎阅读本文章,觉得有用就多来支持一下,没有能帮到您,还有很多文章,希望有一天能帮到您。

H5页面如何实现扫码功能?uniapp如何兼容H5扫码功能?---相关文章


评论区

ddddd

程序员-学习的网站-想学习编程的码农可以进来看看

首页

视频教程

购物车

我的订单