vue3+jsQr实现手机浏览器调用本地摄像头扫描并识别二维码

本文记录了一个使用Vue3、TypeScript和Vite构建的移动端项目,实现了登录后扫描二维码查询班级信息的功能。项目依赖jsQr库进行二维码解析,并结合arcoDesign UI组件库。在本地开发时需使用浏览器手机模式,支持开启和关闭闪光灯。核心组件包括GetQrcode.vue(二维码扫描)和HelloWorld.vue(父组件)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做的项目有个需求是在手机端打开页面,登录之后能在手机上扫描二维码并根据扫描的结果去查询班级情况。别的功能就不说了,移动端扫描二维码这个以前没做过,所以在这里记录一下。
项目用到的技术栈: Vue 3 + TypeScript + Vite + jsQr,UI组件库是 arco Design,可以根据自己的项目改为需要的,这个很好改

git 地址: github地址-拿来即用

这个项目下载下来就能用直接跑通,需要注意的就是在本地开发用浏览器测试的话,需要用浏览器手机模式,并且把子组件 GetQrcode.vue 的52行注释一下(此处代码中也有说明),大家可以去github上下载整个项目在自己电脑上运行测试,也可以在这篇文章中看两个主要组件的代码,可以直接复制使用,大家自行取用。多有不成熟之处,也欢迎大佬指点!

在这里插入图片描述

其实是下载了木木大神的项目,然后把自己遇到的问题改了一下,然后结合自己的需求,稍微修改的项目,项目的 README中也写得比较详细,木木大神的项目地址:https://ext.dcloud.net.cn/plugin?id=7007 https://ask.dcloud.net.cn/article/35409

废话不多说,这里核心的住要是两个组件,子组件GetQrcode.vue 和父组件 HelloWorld.vue
父组件 HelloWorld.vue 的代码:

<template>
  <div class="container">
    <div class="input-container">
      <a-input-search
        ref="qrInput"
        v-model="data.qrCode"
        autofocus
        placeholder="请扫描二维码"
        search-button
        class="w-p-90"
        @change="searchInfo"
        @press-enter="searchInfo"
        @search="searchInfo"
      >
        <template #prefix>
          <icon-scan @click="handleScan" />
        </template>
      </a-input-search>
    </div>
    <GetQrcode
      v-if="data.isQrCodeShown"
      @success="gotQrCode"
      @closeScan="closeScan"
    />
    <a-alert v-if="data.isQrAlert" closable>{
  
  { data.qrCOdeData }}</a-alert>
  </div>
</template>

<script lang="ts" setup>
import {
     
      ref, reactive, onMounted } from "vue";
import {
     
      FormInstance } from "@arco-design/web-vue/es/form";
import GetQrcode from "./GetQrcode.vue";

const qrInput: any = ref<FormInstance>();

// 全局控制的数据
const data = reactive({
     
     
  qrCode: "",
  isQrCodeShown: false,
  isQrAlert: false,
  qrCOdeData: "",
});

// 输入框的search事件
const searchInfo = (val: any) => {
     
     
  console.log("查询");
  console.log(data.qrCode);
  if (qrInput.value) {
     
     
    qrInput.value.focus();
  }
};

// 点击扫描图标---打开扫码功能
const handleScan = () => {
     
     
  const isMobile = checkDevice();
  if (isMobile === true) {
     
     
    data.isQrCodeShown = true;
  }
};

// 检查当前登录设备类型
const checkDevice = () => {
     
     
  // 获取浏览器navigator对象的userAgent属性(浏览器用于HTTP请求的用户代理头的值)
  const info = navigator.userAgent;
  // 通过正则表达式的test方法判断是否包含“Mobile”字符串
  const isMobile = /mobile/i.test(info);
  // 如果包含“Mobile”(是手机设备)则返回true
  return isMobile;
};
// 扫码成功
const gotQrCode = (params: any) => {
     
     
  // 这里params就是二维码的内容,这里可以根据自己项目的需求处理内容
  if (params) {
     
     
    data.isQrAlert = true;
    data.qrCOdeData = params;  // 我这里拿到二维码的内容是弹出框弹出,为了测试
    data.isQrCodeShown = false;
  }
};

const closeScan = () => {
     
     
  // 开发的 时候为了方便,加了这个关闭按钮,正常项目可以去掉
  data.isQrCodeShown = false;
};
</script>

<script lang="ts">
export default {
     
     
  name: "Scan",
  data() {
     
     
    return {
     
     };
  },
};
</script>

### 实现 Vue3 项目中的二维码扫描 为了在 Vue3 项目中集成 `jsQR` 库实现二维码扫描功能,可以按照以下方法操作: #### 安装依赖包 首先,在 Vue3 项目中安装必要的依赖项。可以通过 npm 或 yarn 来完成此过程。 ```bash npm install jsqr ``` 或者使用 Yarn: ```bash yarn add jsqr ``` #### 创建组件结构 创建一个新的 Vue 组件来处理图像上传和显示 QR 码的内容。HTML 部分定义了一个文件输入框用于选择图片,一个 `<canvas>` 元素用来绘制所选图片,展示解码后的 QR 码数据[^3]。 ```html <template> <div class="scanner"> <input type="file" @change="onFileChange" /> <p v-if="decodedText">Decoded Text: {{ decodedText }}</p> <canvas ref="canvas"></canvas> </div> </template> <script setup> import { ref, onMounted } from &#39;vue&#39; import jsQR from &#39;jsqr&#39; const canvas = ref(null) const ctx = ref(null) const decodedText = ref(&#39;&#39;) function drawImageOnCanvas(image) { const img = new Image() img.onload = () => { if (ctx.value === null || !img.complete) return let width = img.width, height = img.height; if (width > height) { // 如果宽度大于高度,则保持宽高比缩小到画布大小 width *= 200 / height; height = 200; } else { // 否则按比例调整尺寸 height *= 200 / width; width = 200; } canvas.value.width = width; canvas.value.height = height; ctx.value.drawImage(img, 0, 0, width, height); decodeQRCode(); }; img.src = URL.createObjectURL(image.files[0]); } async function decodeQRCode() { try { const imageData = ctx.value.getImageData(0, 0, canvas.value.width, canvas.value.height).data; const code = jsQR(imageData, canvas.value.width, canvas.value.height); if (code) { decodedText.value = code.data; } else { console.log("No QR Code found"); } } catch (error) { console.error(error.message); } } </script> <style scoped> .scanner input[type=&#39;file&#39;] { display: block; margin-bottom: 1rem; } </style> ``` 这段代码展示了如何通过监听文件变化事件 (`@change`) 将用户选取的照片加载至页面上的 `<canvas>` 上下文中,调用 `decodeQRCode()` 函数尝试从中提取 QR 码信息[^2]。 当成功解析出有效的 QR 码时,会更新视图上绑定的数据属性 `decodedText` 显示其内容;如果没有找到任何有效编码的信息,则会在控制台打印一条消息指出未发现 QR 码。 关于 `threshold` 参数的选择,默认情况下不需要特别设置它,除非遇到特定场景下的识别问题才考虑微调该参数以优化性能[^4]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值