html5-qrcode扫码功能

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • [H5 扫码功能安装指南](#H5 扫码功能安装指南)
  • 部署环境
      • [5. 错误处理](#5. 错误处理)
    • [🧪 测试建议](#🧪 测试建议)
      • [1. 功能测试](#1. 功能测试)
      • [2. 兼容性测试](#2. 兼容性测试)
      • [3. 异常测试](#3. 异常测试)
      • [4. 性能测试](#4. 性能测试)
    • [📱 移动端优化](#📱 移动端优化)
      • [1. 全屏显示](#1. 全屏显示)
      • [2. 防止滚动穿透](#2. 防止滚动穿透)
      • [3. 触摸友好](#3. 触摸友好)
    • [🔗 参考资料](#🔗 参考资料)
    • [📞 常见问题](#📞 常见问题)
      • [Q1: 为什么摄像头无法启动?](#Q1: 为什么摄像头无法启动?)
      • [Q2: 扫描识别率低怎么办?](#Q2: 扫描识别率低怎么办?)
      • [Q3: 可以同时支持微信小程序吗?](#Q3: 可以同时支持微信小程序吗?)
      • [Q4: 如何更换扫描框样式?](#Q4: 如何更换扫描框样式?)

前言

H5 扫码功能安装指南

📦 安装依赖

bash 复制代码
# 使用 npm
npm install html5-qrcode

# 或使用 pnpm(推荐)
pnpm install html5-qrcode

📁 已创建的文件

1. 扫码组件

  • 文件src/components/QrScanner/index.vue
  • 功能:封装的扫码组件,支持二维码和条形码

2. 核销页面(已更新)

  • 文件src/views/verify/index.vue
  • 功能
    • ✅ 扫码核销
    • ✅ 手动输入核销码
    • ✅ 摄像头切换
    • ✅ 核销结果提示

🚀 使用方法

方式一:直接使用(已集成到核销页)

bash 复制代码
# 1. 安装依赖
pnpm install html5-qrcode

# 2. 启动项目
npm run dev

# 3. 访问核销页面
# 登录后点击"去核销",或直接访问 /verify

方式二:在其他页面使用扫码组件

js 复制代码
<template>
  <div>
    <el-button @click="startScan">开始扫码</el-button>

    <QrScanner
      v-if="isScanning"
      ref="scannerRef"
      @success="onScanSuccess"
      @error="onScanError"
      @close="isScanning = false"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import QrScanner from '@/components/QrScanner/index.vue'

const isScanning = ref(false)
const scannerRef = ref(null)

const startScan = async () => {
  isScanning.value = true
  await nextTick()
  scannerRef.value?.startScan()
}

const onScanSuccess = (code) => {
  console.log('扫码结果:', code)
  // 处理扫码结果
}

const onScanError = (error) => {
  console.error('扫码错误:', error)
}
</script>

🎯 功能特性

扫码组件功能

  • ✅ 支持二维码和条形码
  • ✅ 自动识别后置/前置摄像头
  • ✅ 支持切换摄像头
  • ✅ 扫描框可视化
  • ✅ 防抖处理(2秒内不重复扫描)
  • ✅ 震动反馈(支持的设备)
  • ✅ 错误提示(权限、摄像头等)
  • ✅ 完全响应式(移动端/PC端)

核销页面功能

  • ✅ 立即扫码核销
  • ✅ 手动输入核销码
  • ✅ 核销成功/失败提示
  • ✅ 可连续核销

⚙️ 配置说明

扫码配置

编辑 src/components/QrScanner/index.vue

javascript 复制代码
const config = {
  fps: 10,  // 每秒扫描帧数(1-60),建议 10
  qrbox: { width: 250, height: 250 },  // 扫描框大小
  aspectRatio: 1.0,  // 宽高比
  disableFlip: false,  // 是否禁用翻转识别
  videoConstraints: {
    facingMode: { ideal: 'environment' }  // 优先后置摄像头
  }
}

防抖时间调整

javascript 复制代码
// src/components/QrScanner/index.vue

// 防抖:2秒内不重复扫描(可调整)
const now = Date.now()
if (now - lastScanTime < 2000) {  // 改为 3000 = 3秒
  return
}

🔧 对接后端接口

修改核销接口

编辑 src/views/verify/index.vue

javascript 复制代码
// 核销订单
const verifyOrder = async (code) => {
  try {
    // 1
    import { verifyOrderXApi } from '@/api/verifyXxx'

    // 2. 调用接口
    const res = await verifyOrderApi({ code })

    // 3. 成功处理
    await ElMessageBox.alert(
      `订单号:${res.data.orderId}<br/>
       商品:${res.data.productName}<br/>
       核销成功!`,
      '核销成功',
      {
        dangerouslyUseHTMLString: true,
        confirmButtonText: '继续核销',
        type: 'success'
      }
    )

    isScanning.value = false

  } catch (error) {
    // 4. 失败处理
    ElMessageBox.alert(
      error.message || '核销失败,请稍后重试',
      '核销失败',
      {
        confirmButtonText: '重新扫码',
        type: 'error'
      }
    )
  }
}

创建 API 文件

创建 src/api/verify.js

javascript 复制代码
import request from '@/utils/request'

// 核销订单
export function verifyOrderApi(data) {
  return request({
    url: '/api/verify/order',
    method: 'post',
    data
  })
}

// 查询核销记录
export function getVerifyHistory(params) {
  return request({
    url: '/api/verify/history',
    method: 'get',
    params
  })
}

⚠️ 注意事项

1. HTTPS 要求

摄像头功能必须在 HTTPS 环境下使用(localhost 除外)

部署环境

https://your-domain.com # ✅ 可以使用摄像头

http://your-domain.com # ❌ 不能使用摄像头

复制代码
### 2. 浏览器兼容性

| 浏览器 | 支持版本 | 备注 |
|--------|----------|------|
| Chrome | 53+ | ✅ 完全支持 |
| Safari | 11+ | ✅ 完全支持 |
| Firefox | 36+ | ✅ 完全支持 |
| Edge | 79+ | ✅ 完全支持 |
| 微信内置浏览器 | - | ✅ 支持 |
| QQ浏览器 | - | ⚠️ 需要测试 |

### 3. 摄像头权限

首次使用时浏览器会请求摄像头权限:

┌────────────────────────────────┐

│ 允许访问您的摄像头吗? │

│ │

│ [阻止] [允许] │

└────────────────────────────────┘

复制代码
**如果用户拒绝:**
- 显示错误提示
- 提供手动输入核销码的备用方案
- 引导用户在浏览器设置中开启权限

### 4. 性能优化建议

```javascript
// 1. 扫码成功后立即停止
const onScanSuccess = async (code) => {
  await html5QrCode.stop()  // 停止扫描,释放资源
  handleVerify(code)
}

// 2. 组件卸载时清理
onBeforeUnmount(() => {
  if (html5QrCode) {
    html5QrCode.stop()
    html5QrCode.clear()
  }
})

// 3. 降低扫描帧率(如果性能不佳)
const config = {
  fps: 5  // 降低到 5 帧/秒
}

5. 错误处理

javascript 复制代码
try {
  await html5QrCode.start(...)
} catch (err) {
  if (err.name === 'NotAllowedError') {
    // 用户拒绝授权
    ElMessage.error('请允许访问摄像头')
  } else if (err.name === 'NotFoundError') {
    // 未检测到摄像头
    ElMessage.error('未检测到摄像头')
  } else if (err.name === 'NotReadableError') {
    // 摄像头被占用
    ElMessage.error('摄像头被其他应用占用')
  } else {
    // 其他错误
    ElMessage.error('启动扫码失败')
  }
}

🧪 测试建议

1. 功能测试

  • ✅ 扫描二维码
  • ✅ 扫描条形码
  • ✅ 切换前后摄像头
  • ✅ 取消扫码
  • ✅ 手动输入核销码
  • ✅ 扫码成功/失败提示

2. 兼容性测试

  • ✅ Chrome(移动端/PC端)
  • ✅ Safari(iPhone/iPad/Mac)
  • ✅ 微信内置浏览器
  • ✅ 各种Android浏览器

3. 异常测试

  • ✅ 拒绝摄像头权限
  • ✅ 没有摄像头的设备
  • ✅ 摄像头被占用
  • ✅ 网络断开
  • ✅ 扫描无效二维码

4. 性能测试

  • ✅ 扫描识别速度
  • ✅ 内存占用
  • ✅ CPU占用
  • ✅ 电量消耗(移动端)

📱 移动端优化

1. 全屏显示

js 复制代码
.scanner-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 9999;
}

2. 防止滚动穿透

javascript 复制代码
// 开始扫码时
document.body.style.overflow = 'hidden'

// 停止扫码时
document.body.style.overflow = ''

3. 触摸友好

js 复制代码
.action-btn {
  height: 44px;  // 至少 44px,方便点击
  padding: 0 20px;
}

🔗 参考资料

📞 常见问题

Q1: 为什么摄像头无法启动?

A: 检查以下几点:

  1. 是否在 HTTPS 环境(或 localhost)
  2. 是否授予了摄像头权限
  3. 摄像头是否被其他应用占用
  4. 浏览器是否支持

Q2: 扫描识别率低怎么办?

A: 尝试:

  1. 提高 fps 值(如 fps: 15)
  2. 增大扫描框尺寸
  3. 确保光线充足
  4. 二维码/条形码清晰完整

Q3: 可以同时支持微信小程序吗?

A: 不可以。微信小程序需要使用 wx.scanCode() API。

建议:

  • H5:使用 html5-qrcode
  • 小程序:使用 wx.scanCode()
  • 通过环境判断选择不同方案

Q4: 如何更换扫描框样式?

A: 修改组件样式:

js 复制代码
:deep(#qr-shaded-region) {
  border: 50px solid rgba(0, 0, 0, 0.5) !important;  // 扫描框外阴影
}

:deep(#qr-shaded-region::before) {
  // 自定义扫描框样式
}

相关推荐
2501_906467632 小时前
HTML5结合Vue3实现百万文件分块上传的思路是什么?
前端·html·html5·vue上传解决方案·vue断点续传·vue分片上传下载·vue分块上传下载
San30.2 小时前
现代前端工程化实战:从 Vite 到 React Router demo的构建之旅
前端·react.js·前端框架
kirinlau2 小时前
vue3+vite+scss项目使用tailwindcss
前端·css·scss
阿贾克斯的黎明2 小时前
现代前端的魔法标签:HTML5 语义化标签全解析
前端·html·html5
菠菜盼娣2 小时前
vue3知识点
前端·vue.js
JIngJaneIL2 小时前
基于java+ vue建筑材料管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
土豆12502 小时前
终端自治时代的 AI 开发范式:Claude Code CLI 全方位实操指南
前端·人工智能·程序员
Gazer_S2 小时前
【Vue Router 路由守卫(Navigation Guards)指南:概念、执行顺序、beforeResolve、异步路由组件】
前端·javascript·vue.js