更新记录

1.0.0(2026-09-28) 下载此版本

lf-scan 的 uni-app x / UTS 版本,界面重新设计。

  • 组件(easycom):App 端 auto 模式跳转插件自带全屏扫码页,custom 模式在当前页面内使用 camera 组件取景,api 模式使用系统扫码页
  • UTS 原生能力:Android / iOS 基于 ML Kit 的相册图片识别、短震动、相机权限申请
  • 连续扫码、相同内容去重、一维码二次确认与最小长度校验,系统扫码页可疑码型自动重扫
  • 自动放大:App 端未识别时在 1x / 2.5x 之间切换,双击取景区域手动放大
  • 识别成功震动 / 提示音、闪光灯、相册识别、识别后保存截图
  • 相机权限预检与设置页引导,切后台释放相机、回前台自动恢复
  • 扫码结果解析:网址 / WiFi / vCard / MECARD / 日程 / 电话 / 短信 / 邮件 / 位置 / 商品条码 / JSON
  • Web:getUserMedia + BarcodeDetector,支持 h5Decoder 接入 jsQR / zxing

平台兼容性

uni-app x(4.71)

Chrome Safari Android iOS 鸿蒙 微信小程序
√ - √ 16 - -

lf-scan-x 扫码组件(uni-app x / UTS)

lf-scan 的 uni-app x 版本。组件、页面、工具函数全部使用 .uvue / .uts 编写,App 端识别、震动、权限、相册识别由 UTS 原生插件实现,无第三方依赖。

  • App(Android / iOS):自带全屏扫码页(camera 组件原生取景,Google ML Kit 识别),一行调用;也可在当前页面内嵌入取景;也可使用系统扫码页
  • 鸿蒙 / 微信小程序:系统扫码页 uni.scanCode
  • Web:浏览器 BarcodeDetector,支持接入自定义解码器(jsQR / zxing 等),支持双指缩放
  • 识别准确:默认只启用带校验位的常用一维码,一维码二次确认 + 长度校验,系统扫码页误识别自动重扫
  • 反馈可控:震动、提示音(内置音效)开关真实生效
  • 稳定:相机权限预检、切后台自动恢复、连续扫码、去重
  • 结果解析:网址、WiFi、名片、电话、短信、邮件、地理位置、日程、商品条码、JSON

环境要求

项目 要求
HBuilderX 4.71 及以上(camera 组件扫码模式、uni.openAppAuthorizeSetting)
项目类型 uni-app x(manifest.json 含 uni-app-x 节点)
App 运行 需制作自定义基座(使用了 UTS 原生插件与 uni-barcode-scanning 模块)

平台兼容

平台 自定义界面 系统扫码页 相册识别 说明
App Android ✅ 插件扫码页 / 页面内取景 ✅ uni.scanCode ✅ ML Kit(UTS) 已在真机验证的主要目标平台
App iOS ✅ 插件扫码页 / 页面内取景 ✅ ✅ ML Kit(UTS) UTS iOS 部分需自定义基座真机验证
鸿蒙 – ✅ – 自定义界面自动回退为系统扫码页
微信小程序 – ✅ – 自定义界面自动回退为系统扫码页
Web ✅ getUserMedia + BarcodeDetector – ✅ 需 HTTPS;不支持 BarcodeDetector 的浏览器需传入 h5Decoder

安装

  1. 插件市场点击「使用 HBuilderX 导入插件」,或将 uni_modules/lf-scan-x 复制到项目 uni_modules 目录
  2. 组件遵循 easycom 规范,无需 import 和注册,直接使用 <lf-scan-x>
  3. App 端注册扫码页:导入插件时 HBuilderX 会根据 pages_init.json 提示合并到 pages.json;手动注册时在 pages 中加入(未注册时自动回退为系统扫码页并在控制台提示):
// #ifdef APP-ANDROID || APP-IOS
{
  "path": "uni_modules/lf-scan-x/pages/scan/scan",
  "style": {
    "navigationStyle": "custom",
    "backgroundColorContent": "#000000",
    "backgroundColor": "#000000",
    "bounces": false
  }
}
// #endif
  1. manifest.json:App 端勾选模块 uni-barcode-scanning(相机组件扫码),这是 camera 组件 scanCode 模式的依赖;iOS 在「隐私信息访问的许可描述」中填写相机与相册用途;Android 权限由插件的 AndroidManifest.xml 自动合并(CAMERA、VIBRATE),示例项目也在 manifest 中显式声明了一遍:
"app-android": {
  "distribute": {
    "modules": { "uni-barcode-scanning": {} },
    "permissions": [
      "<uses-permission android:name=\"android.permission.CAMERA\"/>",
      "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
      "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>"
    ]
  }
},
"app-ios": {
  "distribute": {
    "modules": { "uni-barcode-scanning": {} },
    "privacyDescription": {
      "NSCameraUsageDescription": "用于扫描二维码 / 条形码",
      "NSPhotoLibraryUsageDescription": "用于从相册选择图片识别二维码",
      "NSPhotoLibraryAddUsageDescription": "用于保存扫码截图到相册"
    }
  }
}
  1. 制作自定义基座后真机运行(标准基座不包含 UTS 插件与扫码模块)

快速开始

1. 一行接入

<lf-scan-x @success="onSuccess" @fail="onFail" @cancel="onCancel" />
import { LfScanResult, LfScanFail } from '@/uni_modules/lf-scan-x/utils/index.uts'

function onSuccess(res : LfScanResult) {
  console.log(res.result, res.scanType, res.parsed?.type)
}
function onFail(err : LfScanFail) {
  console.log(err.type, err.errMsg)
}

App 端打开插件扫码页,小程序 / 鸿蒙打开系统扫码页,Web 使用浏览器摄像头。识别成功后触发 success,App 端扫码页自动关闭。

2. 通过 ref 调用、自定义按钮

<lf-scan-x ref="scan" :show-trigger="false" @success="onSuccess" />
<button @click="scan?.start()">扫码</button>
const scan = ref<LfScanXComponentPublicInstance | null>(null)

3. 连续扫码

<lf-scan-x ref="scan" :continuous="true" :continuous-interval="1000" @success="onEach" />

每次识别触发一次 success 并震动 / 播放提示音,扫码页底部实时显示已识别数量与最新内容;识别后等待 continuousInterval 再继续,同一个码停留在框内会按该节奏重复回调,去重由业务层按需处理(或设置 dedupeTime)。点击左上角关闭或调用 stop() 结束,结束时触发 stop。

4. 页面内嵌入(App)

uni-app x 的任意页面都可以放置 camera 组件,因此 custom 模式不再区分 vue / nvue:

<template>
  <view style="flex: 1; background-color: #000000">
    <lf-scan-x ref="scan" mode="custom" :auto-start="true" :show-trigger="false" safe-area-top="true"
      @success="onSuccess" @cancel="goBack" @fail="onFail" />
  </view>
</template>

<script setup lang="uts">
  import { LfScanResult, LfScanFail } from '@/uni_modules/lf-scan-x/utils/index.uts'
  const scan = ref<LfScanXComponentPublicInstance | null>(null)
  function onSuccess(res : LfScanResult) { uni.$emit('scan-result', JSON.stringify(res)); uni.navigateBack() }
  function goBack() { uni.navigateBack() }
  function onFail(err : LfScanFail) { uni.showToast({ title: err.errMsg, icon: 'none' }) }
  onUnload(() => { scan.value?.stop() })
</script>

页面建议设置 navigationStyle: custom。组件会自动监听页面的 onPageHide / onPageShow,切后台释放相机、回前台恢复,无需手动调用 pause() / resume()。

5. 系统扫码页

<lf-scan-x mode="api" @success="onSuccess" />

系统扫码页由 uni-app x 内置扫码页提供,其震动与提示音不受 vibrate / sound 控制。App 端关闭系统扫码页不会回调 fail,组件在回到页面后仍无结果时按 cancel 处理。

6. Web 接入自定义解码器

浏览器不支持 BarcodeDetector 时(如 iOS Safari)传入解码函数,以 jsQR 为例:

<lf-scan-x :h5-decoder="decode" @success="onSuccess" />
import jsQR from 'jsqr'
function decode(imageData : any, _ctx : any) : any {
  const code = jsQR(imageData.data, imageData.width, imageData.height)
  return code != null ? { result: code.data, scanType: 'QR_CODE' } : null
}

签名:(imageData, { width, height, canvas }) => string | { result, scanType } | null,支持 Promise。

识别准确率说明

  • barCode 默认只包含 EAN-13 / EAN-8 / UPC-A / UPC-E / Code128,全部带校验位。ITF、Codabar、Code39、RSS 没有校验位,识别引擎对着二维码、文字、条纹都可能"读出"一串甚至一个字符;需要这些码型时显式传入 code39、itf、codabar、rss14、rssexpanded 或 barCodeAll
  • camera 组件返回所有码型,组件按 scanType 在结果端过滤,不在范围内的结果直接丢弃
  • verifyBarcode(默认开启):一维码需连续两次读到相同内容、且长度不少于 4 位才返回;二维码自带纠错不受影响
  • 系统扫码页无法配置码型细节,组件会拦截可疑码型(ITF / Codabar / Code39 / RSS)并自动重扫,最多 2 次
  • 遇到识别异常可开启 :debug="true",控制台会输出 camera 识别事件的原始数据;正常使用请关闭

提升识别率的建议

做法 效果
只扫二维码时设置 :scan-type="['qrCode']" 一维码结果不再参与二次确认,回调更快
双击取景区域 App 端放大 1.5 倍,再次双击复位;也可调用 setZoom()
让码占据扫描框的 1/3 以上,一维码保持水平 ML Kit 对模块过小的码识别率下降
光线不足时打开闪光灯 减少噪点与对焦失败

API

Props

属性 类型 默认值 说明
mode string auto auto:App 插件扫码页 / 小程序系统扫码页 / Web 浏览器扫码;api:始终系统扫码页;custom:当前页面内自定义界面(小程序 / 鸿蒙回退为系统扫码页)
scanType string[] ['qrCode','barCode'] 码类型,见下表
onlyFromCamera boolean false 系统扫码页仅允许相机
autoZoom boolean true 自动放大。Web:对画面中心区域放大识别;App:未识别时在 1x 与 2.5x 之间自动切换(相机支持时),双击或调用 setZoom() 后停止自动切换
autoCharset boolean false 保留字段(uni-app x 引擎自动识别字符集)
barCodeInput boolean false 保留字段
enableAlbum boolean true 允许从相册识别
color string #00E5A0 主题色:默认按钮、闪光灯激活态、默认扫描框 / 扫描线颜色
frameColor string '' 扫描框颜色,为空时使用 color
scanbarColor string '' 扫描线颜色,为空时使用 color
title string 扫一扫 扫码页标题
tip string 将二维码 / 条形码放入框内,即可自动扫描 提示文字
showHeader boolean true 显示标题栏(含关闭按钮)
showFlash boolean true 显示闪光灯按钮
showTrigger boolean true 渲染默认触发按钮
triggerText string 扫一扫 默认按钮文字
showResult boolean true 连续扫码时在底部显示已识别数量与最新内容
autoStart boolean false 挂载后自动开始
continuous boolean false 连续扫码(自定义界面 / Web)
continuousInterval number 1000 连续扫码两次识别最小间隔 ms
dedupeTime number 0 相同内容去重时间 ms,默认不去重
verifyBarcode boolean true 一维码二次确认与长度校验
vibrate boolean true 识别成功震动(自定义界面 / Web)
sound boolean true 识别成功提示音(自定义界面 / Web)
soundSrc string '' 自定义提示音地址,为空使用内置音效
saveImage boolean false 识别成功后拍一张取景截图保存到相册(App)
parse boolean true 解析内容到 result.parsed
permissionTip boolean true 无相机权限时弹窗引导去设置
safeAreaTop string auto 标题栏预留状态栏高度:auto 按页面 navigationStyle 判断,true / false 强制
zIndex number 999 扫码界面层级
pagePath string /uni_modules/lf-scan-x/pages/scan/scan App auto 模式跳转的扫码页路径
debug boolean false 控制台输出识别事件的原始数据
h5Decoder function null Web 自定义解码器
h5Facing string environment Web 摄像头方向
h5ScanInterval number 200 Web 解码间隔 ms

scanType 取值

值 说明
qrCode 二维码
barCode 常用一维码:EAN-13 / EAN-8 / UPC-A / UPC-E / Code128
barCodeAll 全部一维码(含 Code39 / ITF / Codabar / RSS,误识别率较高)
datamatrix / pdf417 / aztec / maxicode 二维码型(aztec / maxicode 仅自定义界面)
ean13 / ean8 / upca / upce / code128 / code93 / code39 / itf / codabar / rss14 / rssexpanded 精确指定一维码(系统扫码页归并为 barCode)

Events

事件 回调参数 说明
success LfScanResult 识别成功
fail LfScanFail:{ errMsg, type, origin } type:permission / unsupported / scan / album / flash / busy
cancel – 用户取消
start – 开始扫码
stop – 扫码结束(扫码页关闭、Web 停止、系统扫码页返回)
flash-change boolean 闪光灯状态变化

LfScanResult

{
  result: 'https://uniapp.dcloud.net.cn',
  scanType: 'QR_CODE',      // QR_CODE EAN_13 CODE_128 DATA_MATRIX PDF_417 ...
  charSet: 'UTF-8',
  path: '',                 // 图片路径(相册识别 / saveImage 截图)
  rawData: '',
  source: 'camera',         // camera | album | api | web
  platform: 'app-android',  // app-android | app-ios | app-harmony | web | mp-weixin
  timestamp: 1700000000000,
  parsed: { type: 'url', url: 'https://uniapp.dcloud.net.cn', raw: '...' },  // parse 为 false 时为 null
  imageSaved: null,
  imageSaveError: null
}

parsed 解析类型(LfScanParsed)

type 字段
url url、scheme
wifi ssid、password、encryption、hidden
vcard / mecard name、tels[]、emails[]、org、title、url、address、note
event summary、start、end、location、description
tel number
sms number、body
email email、subject、body
geo latitude、longitude、altitude
product code、format
json data
text text

UTS 为强类型,LfScanParsed 包含以上全部字段,未使用的字段为 null。

Methods(通过 ref 调用)

方法 说明
start() 开始扫码(别名 startScan())
stop() 停止并释放相机 / 关闭扫码页(别名 stopScan()),系统扫码页不可用
cancel() 停止并触发 cancel
pause() / resume() 暂停 / 恢复识别;组件已自动监听页面显示隐藏,一般无需调用
setFlash(boolean) / toggleFlash() 闪光灯(页面内取景 / Web)
setZoom(number, callback?) 设置缩放倍数(App 页面内取景 / Web),callback 返回实际倍数
chooseImage() 选择相册图片识别(App / Web)
scanImage(path) 识别本地图片(App / Web)
isScanning() 是否扫码中
getLastResult() / getLastImage() 上次结果 / 上次保存的图片路径

Slots

名称 作用域参数 说明
trigger { scanning } 自定义触发按钮,通过 ref 调用 start()

工具函数

import {
  parseScanResult, createScanHistory,
  checkCameraPermission, showPermissionGuide, openAppSettings,
  vibrate, playSound,
  LfScanResult, LfScanFail, LfScanParsed
} from '@/uni_modules/lf-scan-x/utils/index.uts'

@/uni_modules/lf-scan-x 根路径指向 UTS 原生插件,导出 lfDecodeImage、lfVibrate、lfRequestCameraPermission、lfCheckCameraPermission,可在自己的页面中直接使用。

FAQ

1. App 端点击「开始扫码」打开的是系统扫码页 扫码页未在 pages.json 注册,按「安装」第 3 步注册后重新运行;控制台会有 [lf-scan-x] 扫码页面 ... 未注册 提示。

2. 自定义界面黑屏 / 没有画面 确认 manifest.json 勾选了 uni-barcode-scanning 模块并重新打包自定义基座;确认系统设置中已允许相机;开启 :debug="true" 查看控制台的 camera error 事件。

3. 相册识别提示「未识别到二维码 / 条形码」 图片中的码需清晰且不过小;只在 scanType 范围内查找,多个码时返回第一个符合的结果。

4. 震动无效 Android 需要 VIBRATE 权限(插件已声明,需重新打包基座);iOS 使用触感反馈,静音模式或关闭系统触感时不会震动。

5. Web 提示不支持 需要 HTTPS;iOS Safari 等不支持 BarcodeDetector 的浏览器请传入 h5Decoder。

更新日志

见 changelog.md。

许可证

MIT

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android: - android.permission.CAMERA(扫码取景,插件 AndroidManifest.xml 已声明) - android.permission.VIBRATE(识别成功震动,插件 AndroidManifest.xml 已声明) - 读取相册图片:从相册识别二维码时由 uni.chooseImage 按系统版本申请 iOS(需在 manifest.json「隐私信息访问的许可描述」中填写): - NSCameraUsageDescription:扫码取景 - NSPhotoLibraryUsageDescription:从相册选择图片识别 - NSPhotoLibraryAddUsageDescription:saveImage 开启时保存扫码截图到相册(默认关闭) Web:浏览器摄像头权限(getUserMedia) 鸿蒙 / 微信小程序:系统扫码页由平台自行处理权限,插件不额外申请

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件本身不采集任何数据,也不向任何服务器发送数据。扫码识别(相机与相册图片)全部在设备本地完成。 App 端使用的 Google ML Kit Barcode Scanning(Android com.google.mlkit:barcode-scanning 17.2.0、iOS GoogleMLKit/BarcodeScanning 6.0.0,与 uni-app x 官方 uni-barcode-scanning 模块相同版本)在设备本地运行,不上传图像;ML Kit 可能会向 Google 发送用于性能统计的诊断信息,详见 https://developers.google.com/ml-kit/terms

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议

暂无用户评论。