首页 > 其他分享 >vue3 使用 html5-qrcode 实现扫描二维码功能

vue3 使用 html5-qrcode 实现扫描二维码功能

时间:2024-02-23 16:11:43浏览次数:27  
标签:const Html5Qrcode 扫描 devices html5 vue3 qrcode html5QrCode

1. 安装

npm安装

npm install --save-dev html5-qrcode

或直接引入

<script src="https://unpkg.com/html5-qrcode" type="text/javascript">

2. 引入

  1. 根据需求自定义渲染 QR scanning UI 的容器。
<div id="reader" width="600px"></div>
  1. 引入 Html5Qrcode
// 简单模式(使用默认用户界面)
import {Html5QrcodeScanner} from "html5-qrcode";
// 专业模式(使用自己的用户界面)
import {Html5Qrcode} from "html5-qrcode";

Html5QrcodeScanner允许您使用几行代码和默认用户界面实现端到端扫描仪,该用户界面允许使用相机进行扫描或从文件系统中选择图像。
Html5Qrcode类用来设置 QR 码扫描仪(使用您自己的用户界面),并允许用户使用相机或通过选择文件系统中的图像文件或智能手机中的本机相机来扫描 QR 码。

3. 使用

  1. 如果使用 Html5QrcodeScanner,系统默认
// 扫描成功
function onScanSuccess(decodedText, decodedResult) {
  console.log(`Code matched = ${decodedText}`, decodedResult);
}
// 扫描失败
function onScanFailure(error) {
  console.warn(`Code scan error = ${error}`);
}
// 创建并配置实例,渲染扫描仪
let html5QrcodeScanner = new Html5QrcodeScanner(
  "reader",
  { fps: 10, qrbox: {width: 250, height: 250} },
  /* verbose= */ false);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
  1. 如果使用 Html5Qrcode,自定义

获取相机id

// 获取支持的相机列表
Html5Qrcode.getCameras().then(devices => {
  /**
   * devices 类型为对象数组
   * { id: "id", label: "label" }
   */
  if (devices && devices.length) {
    let cameraId = devices[0].id;
    // 开始扫描
  }
}).catch(err => {
  // 处理错误
});

注意:如果未授予相机权限,会触发权限请求申请。
使用相机需要网站使用https协议

开始扫码

// 开始扫码
const html5QrCode = new Html5Qrcode(/* element id */ "reader");
html5QrCode.start(
  cameraId,
  {
    fps: 10,    // 帧率,控制扫描速度
    qrbox: { width: 250, height: 250 }  // 限制要用于扫描的取景器区域
  },
  (decodedText, decodedResult) => {
    // 获取扫描结果
  },
  (errorMessage) => {
    // 结果错误处理
  })
.catch((err) => {
  // 无法扫描时的错误处理
});

您可以选择在构造函数中设置另一个参数,以verbose将所有日志打印到控制台
const html5QrCode = new Html5Qrcode("reader", /* verbose= */ true);

停止

html5QrCode.stop().then((ignore) => {
  // 停止扫描
}).catch((err) => {
  // 停止失败处理
});

其它相关配置
image

4. 完整示例

页面

<template>
  <div class="page-box">
    <div class="qr-container">
      <div class="qr-box">
        <div id="reader"></div>
      </div>
    </div>
    <div class="btn-box">
      <div>
        <van-icon name="arrow-left" @click="clickBack" />
      </div>
      <div>
        <van-uploader
          v-model="state.fileList"
          :preview-image="false"
          :after-read="uploadImg"
        >
          <van-icon name="photo-o"
        /></van-uploader>
      </div>
    </div>
  </div>
</template>

<style scoped>
.page-box {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #000;
}
.qr-container {
  position: relative;
  width: 100%;
  height: 90%;
}
.qr-box {
  height: 100%;
}
#reader {
  top: 50%;
  left: 0;
}
.btn-box {
  flex: 1;
  display: flex;
  justify-content: space-around;
  align-items: flex-start;
  margin-top: auto;
  padding: 12px;
  color: #fff;
  font-size: 28px;
}
</style>

逻辑

<script setup>
import { reactive, onMounted, onUnmounted } from "vue";
import { Html5Qrcode } from "html5-qrcode";
import { showToast } from "vant";

import useVueRouter from "@/hooks/useRouter";
const { goBack } = useVueRouter();

const state = reactive({
  html5QrCode: null,
  fileList: [],
});

onMounted(() => {
  getCamerasInfo();
});
onUnmounted(() => {
  if (state.html5QrCode?.isScanning) {
    stopScan();
  }
});

const clickBack = () => {
  goBack();
};

const getCamerasInfo = () => {
  Html5Qrcode.getCameras()
    .then((devices) => {
      if (devices && devices.length) {
        state.html5QrCode = new Html5Qrcode("reader");
        startScan();
      }
    })
    .catch((err) => {
      showToast({
        message: "摄像头无访问权限!",
        duration: 2000,
      });
    });
};

const startScan = () => {
  state.html5QrCode
    .start(
      { facingMode: "environment" },
      {
        fps: 1,
        qrbox: { width: 250, height: 250 },
      },
      (decodedText, decodedResult) => {
        showToast(decodedText, decodedResult);
      }
    )
    .catch((err) => {
      console.log("扫码失败", err);
    });
};

const stopScan = () => {
  state.html5QrCode
    .stop()
    .then((a) => {
      console.log("已停止扫码", a);
    })
    .catch((err) => {
      console.log(err);
      showToast("停止失败");
    });
};

const uploadImg = () => {
  try {
    window.qrcode.callback = (result) => {
      showToast(result);
    };
    let file = state.fileList[0].file;
    let reader = new FileReader();
    reader.onload = (function () {
      return function (e) {
        window.qrcode.decode(e.target.result);
      };
    })(file);
    reader.readAsDataURL(file);
  } catch (error) {
    console.log(error);
    showToast({
      message: "识别失败!",
      duration: 2000,
    });
  }
};
</script>

5. 相关链接

GitHub地址
官方教程
qrcode.minhazav.dev

标签:const,Html5Qrcode,扫描,devices,html5,vue3,qrcode,html5QrCode
From: https://www.cnblogs.com/lpkshuai/p/18029808

相关文章

  • vue3 ref 获取单个Dom及多个Dom
    获取单个Dom<inputtype="text"ref="inputRef"/>setup(){constinputRef=ref(null)onMounted(()=>{console.log(inputRef.value);})}获取多个Dom<divv-for="(item,index)instate.list":key=&quo......
  • vue3+vite 移动端适配postcss-pxtorem插件
    1、安装插件npmipostcss-pxtorem-D2、与package.json同级目录创建postcss.config.js文件module.exports={plugins:{autoprefixer:{overrideBrowserslist:["Android4.1","iOS7.1",......
  • Web应用_6. Vue3
    title:(在线学习平台)link:(https://www.acwing.com/)cover:(https://cdn.acwing.com/media/activity/surface/log.png)Vue官网1配置环境1.1终端Linux和Mac上可以用自带的终端。Windows上推荐用powershell或者cmd。GitBash有些指令不兼容。1.2安装Nodejs安装地址1......
  • vue3+elment-plus项目,el-diglog的按钮,内部是el-form的子组件,那么保存时,如何触发子组件
    问题:el-diglog的按钮,如何触发内部的form表单提交el-dialog是父组件,cengji是子组件代码如下:<el-dialogv-model="dialogVisible"title="层级结构管理"width="1000"><cengji:tableId="tableId"/><template#footer>......
  • vue3 ts用正则表达式校验两位小数和校验整数的方法
    <el-col:span="12"><el-form-itemlabel="贷款金额"prop="loanAmount"><el-input-numberv-model="props.loanAmount":min="0"@change="checkIntegerNumber('loanAmount')"controls......
  • 若依+vue3配置菜单后设置缓存但实际上切换页签重复请求接口
    刚接触ruoyi,配置菜单时发现一个问题,配置好了,也设置了缓存,但是切换tab页签还是会重复请求接口,配置如图:仅是举例,如上图,系统管理->角色管理列表配置,路由地址是role,缓存也勾选了,但实际上第一次打开角色管理页签第一次请求了数据,再跳转其他页面,回到角色管理页签时,又一次请求了数据,实......
  • vue2.0和vue3.0在同一电脑上运行(超详细步骤)
    由于现在公司项目都是vue2.0项目,个人又需要3.0来学习。所以需要在同一电脑安装两个版本的vue。1.在创建vue2.0和vue3.0两个文件夹,并且局部安装 在vue2文件夹执行命令[email protected](版本根据自身来选择),[email protected]在vue3文件夹执行命令npmin......
  • vue3项目模板:新建一个vite+vue3项目,并做基础化建设
    原文地址:https://blog.csdn.net/weixin_43239880/article/details/130355138新建一个vite+vue3项目,并做基础化建设1.使用npmcreatvite@latest新建一个vue3项目2.生成git仓库3.将prettier的规则加入到eslint中(可选操作,建议有)4.添加commitLint(可选操作,建议有)5.加入UI组件库,以ele......
  • Vue3组合式API之getCurrentInstance详解
    Vue2中,可以通过this来获取当前组件实例; Vue3中,在setup中无法通过this获取组件实例,console.log(this)打印出来的值是undefined。在Vue3中,getCurrentInstance()可以用来获取当前组件实例  vue3官方文档解释let{proxy}=getCurrentInstance(); 在setup中分别打印下面......
  • 记录--源码视角,Vue3为什么推荐使用ref而不是reactive
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助ref 和 reactive 是Vue3中实现响应式数据的核心API。ref 用于包装基本数据类型,而reactive用于处理对象和数组。尽管 reactive 似乎更适合处理对象,但 Vue3官方文档更推荐使用 ref。 我的想法,ref就......