更新记录

1.0.30(2026-10-17)

  • 优化
  • 完善示例工程

1.0.29(2026-10-12)

  • 优化

1.0.28(2026-09-23)

  • 优化鸿蒙端
查看更多

平台兼容性

uni-app(4.65)

Vue2 Vue3 Chrome Chrome插件版本 Safari Safari插件版本 app-vue app-nvue Android iOS 鸿蒙
√ √ √ 1.0.25 √ 1.0.25 √ √ 5.0 12 12
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

uni-app x(4.65)

Chrome Chrome插件版本 Safari Safari插件版本 Android iOS 鸿蒙 微信小程序
√ 1.0.25 √ 1.0.25 5.0 12 12 ×

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × × √

特别提醒

  • 购买本插件前,请先试用、请先试用、请先试用,并充分自测确认满足需求之后再行购买。虚拟物品一旦购买之后无法退款;
  • 如有使用上的疑问、bug,可以进交流群联系作者;
  • 作者可承接各种插件定制;
  • 请在合法范围内使用,若使用本插件做非法开发,本方概不负责;
  • 结合文档和示例demo集成使用(点击右侧“使用HBuilderX导入示例项目”,uniapp-x的完整项目源码在uniapp项目的/static文件夹里面);
  • Android体验Demo安装包 https://www.pgyer.com/hwscanunix
  • HarmonyOS 端组件式扫码仅支持 uni-app x 项目;普通 uni-app 项目仍不支持鸿蒙组件式扫码
  • uniappx的示例工程在uniapp示例工程的static/HWScanTest.zip目录

插件功能

  • 默认扫码(鸿蒙、iOS、Android、Web/H5)
  • 自定义扫描(iOS、Android、鸿蒙、Web/H5)
  • 多码扫描(iOS、Android、鸿蒙;Web/H5 暂按单码降级)
  • 组件式扫码(iOS/Android 使用 <yt-scan>;鸿蒙 uni-app x 使用 <native-view>)
  • 生成码(iOS、Android、鸿蒙;Web/H5 支持 QR、DataMatrix、Aztec)
  • 图片识码 decodeImage(iOS、Android、鸿蒙、Web/H5):支持本地图片 / 网络图片 / base64
  • Web/H5 扫码(Safari、Chrome):基于 ZXing 实现摄像头扫码、相册识码、连续扫码及部分码制生成
  • Web/H5 能力仅供源码授权版使用;试用版和普通授权版调用 Web API 会直接报错,App 端不受影响

组件式扫码的鸿蒙接入方式与 iOS/Android 不同:iOS/Android 继续使用 <yt-scan>;鸿蒙 uni-app x 使用 <native-view> 和 YtHwScanHarmonyNative。完整代码请参考下方组件式扫码示例代码。

插件使用文档

说明:支持13种码制式,可自定义选择支持的码制,扫码时不传默认全部。

参数 对应码制格式
Code128 Code 128
Code39 Code 39
Code93 Code 93
Codabar Codabar
EAN-13 EAN-13
EAN-8 EAN-8
ITF14 ITF14
UPC-A UPC-A
UPC-E UPC_E
QR QR code
PDF417 PDF417
Aztec Aztec
DataMatrix DataMatrix

Web/H5 端说明

Web 端基于内置的 ZXing实现,不需要业务项目另外安装 npm 依赖。同时支持 uni-app 和 uni-app x 项目,API 的导入、方法名和回调方式与 App 端保持一致。

Web 扫码页由 API 在运行时创建全屏 ,业务页面不需要增加组件或 template 节点。当前不支持 Web 端 yt-scan 组件方式,请使用 API 方式调用。

Web/H5 能力对照

API / 能力 Web/H5 支持情况
scanAction 支持后置摄像头单码扫描、相册选图和码制过滤
multiCodeScann 兼容调用,支持尝试选择前/后摄像头;暂不支持同帧多码和多码点选
customScan 支持单次或连续扫码、识别间隔、相册、音效/震动和可用时的手电筒
decodeImage 支持本地图片 URL、网络图片、data URL 和裸 base64;暂不支持真正的多码图片识别
generatingCode 支持生成 QR、DataMatrix、Aztec,结果为可直接显示的 data URL
deletePathFile Web 无权删除用户设备上的任意路径文件,仅保留占位并回调 false
组件式扫码 Web 暂不支持;iOS / Android 使用 <yt-scan>,鸿蒙使用 <native-view>

Web/H5 扫码界面

  • 手电筒图标位于扫码框下方并水平居中;只有浏览器和当前摄像头轨道都支持 torch 时才会显示。
  • deletePathFile 在 Web 无权删除用户设备上的任意路径文件,因此保留为占位方法并固定回调 false。

如需自定义 Web/H5 扫码页图标,直接替换 utssdk/web/assets 中对应的同名 PNG:

文件 用途
navigate_back.png 左上角关闭图标
scankit_album.png 右上角选择相册图标
button_flash_on.png 手电筒当前关闭时显示的“开启”图标
button_flash_off.png 手电筒当前开启时显示的“关闭”图标

图标通过 new URL(..., import.meta.url) 交给 Web 编译器处理,不依赖宿主项目的固定部署路径。建议使用透明背景 PNG;替换后需重新运行或发行 Web,如仍显示旧图请清理项目编译缓存。

Web 新增错误码:

错误码 说明
9010003 浏览器没有可用摄像头 API,通常需要检查 HTTPS 或浏览器兼容性
9010004 摄像头权限被拒绝或摄像头启动失败
9010005 当前 Web 环境不支持该能力(预留占位错误码)

Web 端内置 ZXing 代码遵循 Apache License 2.0,许可证位于 utssdk/web/vendor/ZXING-LICENSE。

扫码默认模式(iOS、Android、鸿蒙、Web/H5)

scanAction({
    params: {
    album: true,//是否需要扫描相册
    scanTypes: ["QR", "EAN-13", "Aztec"],//识别的码制式 可选参数,不传默认识别所以的码制式
    multiMode: true//仅鸿蒙有效,默认false
    },
    success: (res => {
        console.log(res)
        //res.sceneType
        //码内容
        this.title = res.result
    })
})

多码扫描(iOS、Android、鸿蒙;Web/H5 暂按单码降级)

multiCodeScann({
    cameraFacing: 'back',//可选字符串,'back' 后置、'front' 前置;不传或传入其他值默认后置,兼容旧版本
    album: true,//是否显示选相册按钮
    isSelectOne: true,//后置摄像头是否多选一,默认true
    scanTitle: "标题",//导航标题
    mulitiCodeMes: "扫描到多码请选择一个",//多码选一时提示文案
    scanTypes: ["EAN-8", "EAN-13", "QR"],//支持码制式集合不传或传[]标识支持识别以下所有码制式 'EAN-8' | 'EAN-13' | 'UPC-A' | 'UPC-E' | 'Codabar' | 'Code39' | 'Code93' | 'Code128' | 'ITF14' | 'QR' | 'DataMatrix' | 'PDF417' | 'Aztec' | 'Other'
    isSound: true,//扫码成功播放音效与震动
    scanResultHandler: (res) => {
        console.log(res)
    }
} as MulitiCodeOptions) //uniapp/非ts项目去掉as MulitiCodeOptions

前置摄像头调用示例:

multiCodeScann({
    cameraFacing: 'front',
    album: true,
    // iOS / Android App 前置摄像头固定为 false;即使传入 true 也不会进入多选一模式
    isSelectOne: false,
    scanResultHandler: (res) => {
        // iOS / Android App 前置摄像头会一次返回当前识别到的所有码
        console.log(res)
    }
} as MulitiCodeOptions) //uniapp/非ts项目去掉as MulitiCodeOptions

iOS / Android 前置摄像头限制: 多码模式使用前置摄像头时不支持“多选一”,isSelectOne 固定为 false,传入的值无效;scanResultHandler 会一次返回当前识别到的所有码。后置摄像头仍支持通过 isSelectOne 控制是否多选一。

鸿蒙限制: 当前 ScanKit 的 customScan 未暴露前后摄像头切换 API。传入 cameraFacing: 'front' 时会记录提示并按系统默认后置摄像头扫码;后置场景支持同帧多码点选、取消恢复、成功音效和震动。

Web/H5 多码降级说明: Web 不支持同帧多码及多码点选。无论使用前置还是后置摄像头,isSelectOne 都无实际作用;识别到第一个码后关闭扫码页,并通过 scanResultHandler 返回长度为 1 的字符串数组。该降级说明不会显示在扫码界面上。

  • 多码扫描参数说明 参数是自定义的MulitiCodeOptions类型参数,ts/uts项目需加上 as MulitiCodeOptions 如上方示例代码
参数 值类型 说明
album bool 是否显示选相册按钮
cameraFacing String 可选字符串。back 使用后置摄像头,front 使用前置摄像头;不传或传入其他值默认 back,兼容旧版本。Web 端是向浏览器发出期望方向,实际选择取决于设备与浏览器
isSelectOne bool iOS / Android / 鸿蒙后置摄像头是否多选一,默认 true;iOS / Android App 前置摄像头固定为 false。鸿蒙当前始终使用系统默认后置摄像头;Web 端不支持多码点选,该值无实际作用
scanTitle String 导航标题
mulitiCodeMes String 多码选一时提示文案
scanTypes [String] 支持的码制式(数组中的值需为上表13种码制式中包含的值)
scanResultHandler function 扫描回调返回字符串数组

自定义扫码(iOS、Android、鸿蒙、Web/H5)

customScan({
    album: true,//是否显示选相册按钮
    scanTypes: ["QR", "EAN-13", "Aztec"],//支持码制式集合不传或传[]标识支持识别以下所有码制式 'EAN-8' | 'EAN-13' | 'UPC-A' | 'UPC-E' | 'Codabar' | 'Code39' | 'Code93' | 'Code128' | 'ITF14' | 'QR' | 'DataMatrix' | 'PDF417' | 'Aztec' | 'Other'
    scanContinue: isContinue,//是否连续扫码
    scanInterval: 3,//连续扫码间隔
    showLightBtn: true,//是否显示手电筒
    scanTitle: '自定义扫码11',//自定义导航标题
    isSound: true,//扫码成功播放音效与震动
    scanResultHandler: (res) => {
        this.title = res.code ?? ''
        console.log(`扫描结果:${res.code} 识别码制式:${res.formatValue}`)
    }
} as CustomScanOptions) //uniapp/非ts项目去掉as CustomScanOptions
  • 自定义扫描参数说明 参数是自定义的CustomScanOptions类型参数,ts/uts项目需加上 as CustomScanOptions 如上方示例代码
参数 值类型 说明
album bool 是否显示选相册按钮
scanContinue bool 是否连续扫码
scanInterval number 连续扫码间隔,单位秒
isSound bool 扫码成功播放音效与震动
showLightBtn bool 是否允许显示手电筒按钮;Web/H5 还需浏览器和摄像头轨道支持 torch
scanTypes [String] 支持的码制式(数组中的值需为上表13种码制式中包含的值)
scanTitle string 导航标题
scanResultHandler function 扫描回调

图片识码 decodeImage(iOS、Android、鸿蒙、Web/H5)

不打开相机,直接识别图片中的码信息。支持三种入参:

  1. 本地路径:uni.chooseImage 返回的 tempFilePath、绝对路径、file://...(鸿蒙相册 URI 如 file://media/... 亦可)
  2. 网络图片:https://...(建议 HTTPS)
  3. base64:纯 base64,或带前缀 data:image/png;base64,xxxx
import { decodeImage } from '@/uni_modules/yt-uts-hwscan'

// 1)本地图:先选图再识码(推荐)
uni.chooseImage({
    count: 1,
    sourceType: ['album', 'camera'],
    success: (chooseRes) => {
        decodeImage({
            params: {
                image: chooseRes.tempFilePaths[0],
                scanTypes: ['QR', 'EAN-13'], // 可选,不传识别全部
                multiMode: false // 可选,是否多码,默认 false
            },
            success: (res) => {
                // res.result 码内容
                // res.results 多码时的码值数组(multiMode: true)
                // res.formatValue / res.sceneType 码制式
                console.log(res)
            },
            fail: (err) => {
                // 9010001:图片为空或加载失败
                // 9010002:图中未识别到码
                console.log(err.errCode, err.errMsg)
            },
            complete: (res) => {
                console.log(res)
            }
        })
    }
})

// 2)网络图
decodeImage({
    params: {
        image: 'https://example.com/qr.png'
    },
    success: (res) => {
        console.log(res.result)
    }
})

// 3)base64
decodeImage({
    params: {
        image: 'data:image/png;base64,iVBORw0KGgo...'
        // 或裸 base64:'iVBORw0KGgo...'
    },
    success: (res) => {
        console.log(res.result)
    }
})
  • 图片识码参数说明(DecodeImageOptions)
参数 值类型 说明
params.image string 必填。本地路径 / 网络 URL / base64
params.scanTypes [String] 可选。支持的码制式,不传识别全部
params.multiMode bool 可选。是否多码识别,默认 false;为 true 时看 res.results。Web 端暂时最多返回一个结果
success function 成功回调
fail function 失败回调
complete function 结束回调(成功或失败都会走)
  • 成功回调 DecodeImageResult
字段 说明
result 单码码值(多码时为第一个)
results 多码码值数组(multiMode: true 时)
formatValue 码制式
sceneType 场景/码制式(与各端实现一致)
  • 错误码
errCode 说明
9010001 图片为空或加载失败
9010002 图中未识别到码

说明:请在真机测试。鸿蒙本地图建议用 uni.chooseImage 返回的路径;直接传 /static/xxx.png 可能无法被系统识码 API 访问。Web 端的网络图片还需要图片服务器允许 CORS。

component方式集成(iOS、Android、鸿蒙)

iOS、Android 继续使用下面已有的 <yt-scan> 兼容组件。鸿蒙目前不支持该兼容组件模型, 因此 uni-app x 的 .uvue 页面需要参考本项目 yt-vlc 的实现,使用 <native-view> + YtHwScanHarmonyNative 挂载原生 ArkUI 预览。

鸿蒙组件只渲染相机画面,不内置扫描框、扫描线、标题、相册或手电筒按钮。页面可以在 native-view 上层自行绘制 UI,再调用 albumRecognition() 和 switchFlashlight()。

鸿蒙 uni-app x 组件示例

<template>
    <view class="scan-page">
        <!-- @init 返回原生元素;@onEvent 是鸿蒙 native-view 的统一事件出口 -->
        <native-view class="scan-preview" @init="onScanInit" @onEvent="onScanEvent"></native-view>

        <!-- 组件不内置按钮,业务可完全控制位置和样式 -->
        <view class="scan-actions">
            <button @click="openAlbum">相册</button>
            <button @click="toggleFlash">手电筒:{{ flashlightOn ? '开' : '关' }}</button>
        </view>
    </view>
</template>

<script setup lang="uts">
    import { YtHwScanHarmonyNative } from '@/uni_modules/yt-uts-hwscan'

    let harmonyScan : YtHwScanHarmonyNative | null = null
    const flashlightOn = ref(false)

    function onScanInit(event : UniNativeViewInitEvent) {
        // detail 是事件数据包装对象;真正的 UniNativeViewElement 在 detail.element。
        const element = event.detail.element
        // 参数依次为:native-view、是否连续扫码、间隔秒数、支持码制;[] 表示全部码制。
        harmonyScan = new YtHwScanHarmonyNative(element, true, 3, ['QR', 'EAN-13'])
    }

    function onScanEvent(event : UniNativeViewEvent) {
        const detail = event.detail as UTSJSONObject
        const opt = detail['opt'] as string
        if (opt == 'recognitionHandler') {
            const code = detail['code'] as string
            const formatValue = detail['formatValue'] as string
            console.log(`扫描结果:${code},码制:${formatValue}`)
        } else if (opt == 'recognitionFail') {
            // 相册没有识别到码、相机权限或 ScanKit 出错时进入这里。
            console.log(`识别失败:${detail['message']}`)
        } else if (opt == 'lightStatusChanged') {
            flashlightOn.value = detail['value'] as boolean
        }
    }

    function openAlbum() {
        harmonyScan?.albumRecognition()
    }

    function toggleFlash() {
        harmonyScan?.switchFlashlight()
    }

    // 必须释放原生控制器,否则离开页面后相机仍可能被占用。
    onUnmounted(() => {
        harmonyScan?.destroy()
        harmonyScan = null
    })
</script>

<style>
    .scan-page { flex: 1; position: relative; background-color: #000; }
    .scan-preview { position: absolute; left: 0; right: 0; top: 0; bottom: 0; }
    .scan-actions {
        position: absolute;
        left: 20px;
        right: 20px;
        bottom: 40px;
        flex-direction: row;
        justify-content: space-between;
    }
</style>

鸿蒙事件载荷与 iOS/Android 语义对应如下:

detail.opt 字段 对应事件
recognitionHandler code、formatValue 扫码或相册识别成功
recognitionFail message 相册无结果、权限或 ScanKit 错误
lightStatusChanged value: boolean 手电筒切换后的状态

YtHwScanHarmonyNative 仅在 APP-HARMONY 分支使用。若同一个 .uvue 页面还要编译到 iOS/Android,请用条件编译让鸿蒙渲染 <native-view>,其他两端继续渲染 <yt-scan>。

下面的 <yt-scan> 写法仅在 uni-app/nvue 和 uni-app x/uvue 的 iOS、Android 端有效,可使用 CSS 设置窗口大小。对于 Android 半屏预览图像变形问题,可将预览设置为全屏,再用绝对定位 的业务视图覆盖不需要显示的区域。

uniapp nvue页面组件式示例代码

<template>
    <view class="content">
        <yt-scan ref="hwscan" class="scan-view" :scanInterval="scanInterval" :scan-types="scanTypes"
            :continueScan="continueScan" @recognitionHandler="recognitionHandler"
            @lightStatusChanged="lightStatusChanged" @recognitionFail="recognitionFail"></yt-scan>
        <view class="btn_bg">
            <view class="btn" @click="alblue()">相册</view>
            <view class="btn" @click="flashlightSwitch()">手电筒状态:{{flashlightStatus?"开":"关"}}</view>
        </view>
    </view>
</template>

<script>
    import * as hwScan from '@/uni_modules/yt-uts-hwscan'
    export default {
        data() {
            return {
                scanTypes: [], //支持码制式集合不传或传[]标识支持识别以下所有码制式 'EAN - 8' | 'EAN - 13' | 'UPC - A' | 'UPC - E' | 'Codabar' | 'Code39' | 'Code93' | 'Code128' | 'ITF14' | 'QR' | 'DataMatrix' | 'PDF417' | 'Aztec' | 'Other'
                continueScan: true, //是否连续扫码----(设置为false android会一直快速触发回调,iOS扫一次后就会黑屏关闭摄像头),设置为true会根据设置的scanInterval触发回调
                scanInterval: 3, //连续扫码间隔--默认3秒
                flashlightStatus: false
            }
        },
        methods: {
            //相册识别
            alblue() {
                this.$refs["hwscan"].albumRecognition()
            },
            //开关手电筒
            flashlightSwitch() {
                this.$refs["hwscan"].switchFlashlight()
            },
            //扫码成功回调
            recognitionHandler(res) {
                let value = res.detail.code ?? "";
                let type = res.detail.formatValue ?? "";
                uni.showToast({
                    title: `扫描结果:${value}`,
                    icon: 'none'
                })
                console.log(`扫描结果:${value} ---- 码制式:${type}`)
            },

            //相册识别失败回调
            recognitionFail() {
                uni.showToast({
                    title: "相册识别失败",
                    icon: 'none'
                })
            },
            //手电筒状态监听
            lightStatusChanged(res) {
                console.log(`手电筒状态:${res.detail ? '开' : '关'}`)
                this.flashlightStatus = res.detail
            },

        }
    }
</script>

<style>
    .content {
        display: flex;
        width: 750rpx;
        flex-direction: column;
        position: relative;
        flex: 1;
    }

    .scan-view {
        position: absolute;
        width: 750rpx;
        left: 0;
        bottom: 0;
top: 0;
    }

    .btn_bg {
        display: flex;
        flex-direction: row;
        background-color: #fff;
        position: absolute;
        left: 0;
        width: 750rpx;
        bottom: 0;
        height: 800rpx;
    }

    .btn {
        width: 220rpx;
        height: 80rpx;
        background-color: chocolate;
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 20rpx;
        border-radius: 8rpx;
        overflow: hidden;
    }
</style>

uniapp-x uvue页面组件式示例代码

<template>
    <view class="content">
        <!-- 相机预览固定为 750rpx 高;工具按钮作为普通 uni-app 视图叠放在左上角。 -->
        <view class="preview-wrap">
            <!-- #ifdef APP-HARMONY -->
            <!-- 鸿蒙不支持兼容式组件,按 yt-vlc 的方式把 ArkUI 预览挂到 native-view。 -->
            <native-view class="scan-view" @init="harmonyScanInit" @onEvent="harmonyScanEvent"></native-view>
            <!-- #endif -->
            <!-- #ifndef APP-HARMONY -->
            <!-- iOS/Android 保持原有 yt-scan 组件及事件,不改动两端实现。 -->
            <yt-scan ref="hwscan" class="scan-view" :scanInterval="scanInterval" :scan-types="scanTypes"
                :continueScan="continueScan" @recognitionHandler="recognitionHandler"
                @lightStatusChanged="lightStatusChanged" @recognitionFail="recognitionFail"></yt-scan>
            <!-- #endif -->

            <view class="preview-tools">
                <!-- 相册识码。图标来自项目 static 目录,不依赖插件内部资源。 -->
                <view class="tool-btn" @click="alblue()">
                    <image class="tool-icon" src="/static/photo.png" mode="aspectFit"></image>
                </view>
                <!-- 根据当前状态切换手电筒图标,点击后仍调用原组件公开方法。 -->
                <view class="tool-btn" @click="flashlightSwitch()">
                    <image class="tool-icon"
                        :src="flashlightStatus ? '/static/flashlight_on.png' : '/static/flashlight_off.png'"
                        mode="aspectFit"></image>
                </view>
            </view>
        </view>

        <!-- 连续扫码的结果保留在预览下方,新增结果后自动滚动到最后一项。 -->
        <scroll-view class="result-scroll" scroll-y="true" :scroll-into-view="resultScrollId"
            scroll-with-animation="true">
            <view v-if="scanResults.length == 0" class="result-empty">扫码结果将在这里显示</view>
            <view v-for="(item, index) in scanResults" :key="index" :id="'scan-result-' + index"
                class="result-item">
                <text class="result-index">{{index + 1}}</text>
                <view class="result-content">
                    <text class="result-code">{{item.code}}</text>
                    <text class="result-type">码制式:{{item.formatValue}}</text>
                </view>
            </view>
        </scroll-view>
    </view>
</template>

<script>
    import *as hwScan from '@/uni_modules/yt-uts-hwscan'

    /** 示例页用于展示的轻量结果模型,不影响插件返回结构。 */
    type ScanDisplayItem = {
        code : string,
        formatValue : string
    }

    export default {
        data() {
            return {
                scanTypes: [] as string[],//支持码制式集合不传或传[]标识支持识别以下所有码制式 'EAN - 8' | 'EAN - 13' | 'UPC - A' | 'UPC - E' | 'Codabar' | 'Code39' | 'Code93' | 'Code128' | 'ITF14' | 'QR' | 'DataMatrix' | 'PDF417' | 'Aztec' | 'Other'
                continueScan: true,//是否连续扫码----设置为false会一直快速触发回调,设置为true会根据设置的scanInterval触发回调
                scanInterval: 3,//连续扫码间隔--默认3秒
                flashlightStatus: false,
                scanResults: [] as ScanDisplayItem[],
                resultScrollId: '',
                // #ifdef APP-HARMONY
                harmonyScan: null as hwScan.YtHwScanHarmonyNative | null
                // #endif
            }
        },
        methods: {
            //相册识别
            alblue() {
                // #ifdef APP-HARMONY
                this.harmonyScan?.albumRecognition()
                // #endif
                // #ifndef APP-HARMONY
                (this.$refs["hwscan"] as YtScanElement).albumRecognition()
                // #endif
            },
            //开关手电筒
            flashlightSwitch() {
                // #ifdef APP-HARMONY
                this.harmonyScan?.switchFlashlight()
                // #endif
                // #ifndef APP-HARMONY
                (this.$refs["hwscan"] as YtScanElement).switchFlashlight()
                // #endif
            },
            // #ifdef APP-HARMONY
            /** native-view 初始化时创建鸿蒙扫码控制器;参数与 iOS/Android props 对齐。 */
            harmonyScanInit(res : UniNativeViewInitEvent) {
                // UniNativeViewInitEvent.detail 是包装对象,真正的原生元素在 detail.element。
                // 不能把整个 detail 传入,否则运行时找不到 bindHarmonyWrappedBuilder。
                const element = res.detail.element
                this.harmonyScan = new hwScan.YtHwScanHarmonyNative(
                    element,
                    this.continueScan,
                    this.scanInterval,
                    this.scanTypes
                )
            },
            /** 鸿蒙 native-view 用 opt 区分与 iOS/Android 同语义的三个事件。 */
            harmonyScanEvent(res : UniNativeViewEvent) {
                const detail = res.detail as UTSJSONObject
                const opt = detail['opt'] as string
                if (opt == 'recognitionHandler') {
                    const value = detail['code'] as string
                    const type = detail['formatValue'] as string
                    this.appendScanResult(value, type)
                } else if (opt == 'recognitionFail') {
                    this.recognitionFail()
                } else if (opt == 'lightStatusChanged') {
                    this.flashlightStatus = detail['value'] as boolean
                }
            },
            // #endif
            //扫码成功回调
            // #ifdef APP-IOS
            recognitionHandler(res) {
                let value = res.detail.code ?? "";
                let type = res.detail.formatValue ?? "";
                this.appendScanResult(value, type)
            },
            // #endif
            // #ifdef APP-ANDROID
            recognitionHandler(res : hwScan.CustomScanResult) {
                let value = res.code ?? "";
                let type = res.formatValue ?? "";
                this.appendScanResult(value, type)
            },
            // #endif

            /**
             * 三端扫码结果统一追加到滚动列表。
             * resultScrollId 指向最新一项,使连续扫码时始终能看到最后识别到的内容。
             */
            appendScanResult(value : string, type : string) {
                this.scanResults.push({
                    code: value,
                    formatValue: type
                } as ScanDisplayItem)
                this.resultScrollId = `scan-result-${this.scanResults.length - 1}`
                console.log(`扫描结果:${value} ---- 码制式:${type}`)
            },

            //相册识别失败回调
            recognitionFail() {
                uni.showToast({
                    title: "相册识别失败",
                    icon: 'none'
                })
            },
            //手电筒状态监听
            // #ifdef APP-IOS
            lightStatusChanged(res) {
                console.log(`手电筒状态:${res.detail ? '开' : '关'}`)
                this.flashlightStatus = res.detail
            },
            // #endif
            // #ifdef APP-ANDROID
            lightStatusChanged(res : boolean) {
                console.log(`手电筒状态:${res ? '开' : '关'}`)
                this.flashlightStatus = res
            },
            // #endif
        }
        // #ifdef APP-HARMONY
        ,
        unmounted() {
            // 页面离开必须释放相机;destroy 可重复调用。
            this.harmonyScan?.destroy()
            this.harmonyScan = null
        }
        // #endif
    }
</script>

<style>
    .content {
        display: flex;
        width: 750rpx;
        flex-direction: column;
        flex: 1;
        background-color: #f5f6f8;
    }

    .preview-wrap {
        position: relative;
        width: 750rpx;
        height: 750rpx;
        flex-shrink: 0;
        background-color: #000;
    }

    .scan-view {
        width: 750rpx;
        height: 750rpx;
    }

    .preview-tools {
        display: flex;
        flex-direction: row;
        position: absolute;
        left: 24rpx;
        top: 24rpx;
        z-index: 10;
    }

    .tool-btn {
        width: 76rpx;
        height: 76rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-right: 20rpx;
        border-radius: 38rpx;
        background-color: rgba(0, 0, 0, 0.42);
        overflow: hidden;
    }

    .tool-icon {
        width: 48rpx;
        height: 48rpx;
    }

    .result-scroll {
        width: 750rpx;
        flex: 1;
        background-color: #f5f6f8;
    }

    .result-empty {
        padding: 48rpx 30rpx;
        color: #999;
        font-size: 28rpx;
        text-align: center;
    }

    .result-item {
        display: flex;
        flex-direction: row;
        align-items: flex-start;
        margin: 20rpx 24rpx 0;
        padding: 24rpx;
        border-radius: 12rpx;
        background-color: #fff;
    }

    .result-index {
        width: 48rpx;
        height: 48rpx;
        border-radius: 24rpx;
        color: #fff;
        background-color: #42c0fb;
        font-size: 24rpx;
        line-height: 48rpx;
        text-align: center;
    }

    .result-content {
        display: flex;
        flex: 1;
        flex-direction: column;
        margin-left: 20rpx;
    }

    .result-code {
        color: #222;
        font-size: 30rpx;
        line-height: 42rpx;
    }

    .result-type {
        margin-top: 8rpx;
        color: #888;
        font-size: 24rpx;
        line-height: 34rpx;
    }
</style>

构建码使用说明

// 调用同步方法示例
generatingCode({
    params: {
        width: 400,
        height: 400,
        codeContent: '6932607220526',
        formatValue: 'QR',
        backgroundColor: "#ff00ff",//码图背景色,默认白色;Android、鸿蒙、Web/H5 有效
        bitMargin: 1,//码图边框宽度,默认 1;Android、鸿蒙、Web/H5 有效
        bimapColor: "#00ff00",//码图颜色,默认黑色;Android、鸿蒙、Web/H5 有效
        logo: "/static/logo.png"//二维码中间 logo;Android、鸿蒙有效,Web/H5 仅 QR 有效
    },
    success: (RES => {
        this.imageResult = RES.filePath
        // iOS/Android:一般为本地文件路径
        // 鸿蒙:为便于 <image> 展示,可能返回 data:image/png;base64,...
        // Web/H5:返回 data:image/png;base64,...
    })
})

构建码参数有要求详情见官网

  • 参数说明
参数 值类型 说明
width int 宽度(鸿蒙建议 ≥200)
height int 高度(鸿蒙建议 ≥200)
codeContent String 内容
formatValue String 码制式(参照上方scanType表)
backgroundColor String(HEX字符串) 码图背景色,默认白色;Android、鸿蒙、Web/H5 有效
bimapColor String(HEX字符串) 码图颜色,默认黑色;Android、鸿蒙、Web/H5 有效
logo String 二维码中间 logo 路径;Android、鸿蒙有效,Web/H5 仅 QR 有效
bitMargin number 码图边框宽度,默认 1;Android、鸿蒙、Web/H5 有效

说明:iOS 端生成码目前主要使用宽高、内容、码制式。Web/H5 当前仅支持生成 QR、DataMatrix、Aztec;Logo 仅对 QR 生效。

删除指定路径下文件(图片)

deletePathFile({
    path: this.imageResult,//文件路径
    resultBackcall: (res => {
        if (res) {
            uni.showToast({
                title: '删除成功',
                icon: "none"
            })
        } else {
            uni.showToast({
                title: '删除失败',
                icon: "none"
            })
        }
    })
})

鸿蒙端默认扫码

<script>
    import * as Scan from '../../uni_modules/yt-uts-hwscan'
    export default {
        data() {
            return {
                title: 'Hello'
            }
        },
        onLoad() {

        },
        methods: {
            scanAction() {
                Scan.scanAction({
                    params: {
                        album: true,
                        scanTypes: ["EAN-8", "EAN-13"]
                    },
                    success: (res) => {
                        console.log(res.result)
                    }
                })
            }
        }
    }
</script>

uni-app x示例代码

<template>
    <view class="content">
        <image class="logo" :src="imageResult"></image>
        <view class="text-area">
            <text class="title" @click="scan()">扫码</text>
            <text class="title" style="margin: 40rpx 0;" @click="multiCodeScannAction()">扫多码</text>
            <view style="display: flex;flex-direction: row;">
                <text class="title" style="margin: 40rpx 0;" @click="customScanAction(true)">自定义连续扫码</text>
                <text class="title" style="margin: 40rpx 40rpx;" @click="customScanAction(false)">自定义非连续扫码</text>
            </view>
            <text class="title" style="margin: 40rpx 0;" @click="generatingCodeAction()">生成码</text>
            <text style="margin-top: 100rpx;" class="title">扫码结果:{{title}}</text>

            <view @click="deletePathFileAction()"
                style="margin-top: 100rpx;background-color: burlywood;padding: 10rpx;">删除指定路径图片
            </view>
        </view>
    </view>
</template>

<script>
    import {
        scanAction,
        generatingCode,
        ScanApiOptions,
        GeneratingCodeOptions,
        ScanParams,
        deletePathFile,
        ScanResult,
        GeneratingParams,
        DeleteFileParams,
        multiCodeScann,
        MulitiCodeOptions,//多码扫描参数
        CustomScanOptions,
        customScan
    } from "@/uni_modules/yt-uts-hwscan";
    export default {
        data() {
            return {
                title: 'Hello',
                imageResult: "/static/logo.png"
            }
        },
        methods: {
            generatingCodeAction() {
                // 调用同步方法示例
                generatingCode({
                    params: {
                        width: 300,
                        height: 300,
                        codeContent: '6932607220526',
                        formatValue: 'Aztec',
                    } as GeneratingParams,
                    success: (RES => {
                        this.imageResult = RES.filePath
                        console.log(RES)
                    })
                } as GeneratingCodeOptions)
            },
            deletePathFileAction() {
                deletePathFile({
                    path: this.imageResult,
                    resultBackcall: (res => {
                        if (res) {
                            uni.showToast({
                                title: '删除成功',
                                icon: "none"
                            })
                        } else {
                            uni.showToast({
                                title: '删除失败',
                                icon: "none"
                            })
                        }
                    })
                } as DeleteFileParams)
            },
            scan() {
                scanAction({
                    params: {
                        album: true,
                        scanTypes: ["QR", "EAN-13", "Aztec"],
                        multiMode: true//鸿蒙端有效,是否支持多码
                    } as ScanParams,
                    success: (res => {
                        console.log(res)
                        this.title = res.result ?? ''
                    })
                } as ScanApiOptions)
            },
            multiCodeScannAction() {
                multiCodeScann({
                    album: true,//是否显示选相册按钮
                    isSelectOne: true,//是否多选一,默认true
                    scanTitle: "多码标题",//多码导航标题
                    mulitiCodeMes: "扫描到多码请选择一个",//多码选一时提示文案
                    scanTypes: ["EAN-8", "EAN-13", 'QR'],//支持码制式集合不传或传[]标识支持识别以下所有码制式 'EAN - 8' | 'EAN - 13' | 'UPC - A' | 'UPC - E' | 'Codabar' | 'Code39' | 'Code93' | 'Code128' | 'ITF14' | 'QR' | 'DataMatrix' | 'PDF417' | 'Aztec' | 'Other'
                    isSound: true,
                    scanResultHandler: (res) => {
                        console.log(res)
                        this.title = res.join(",")
                    }
                } as MulitiCodeOptions)
            },
            //自定义扫码
            customScanAction(isContinue : boolean) {
                customScan({
                    album: true,
                    scanTypes: ["QR", "EAN-13", "Aztec"],
                    scanContinue: isContinue,
                    scanInterval: 3,
                    showLightBtn: true,
                    scanTitle: '自定义扫码11',
                    isSound: true,
                    scanResultHandler: (res) => {
                        this.title = res.code ?? ''
                        console.log(`扫描结果:${res.code} 识别码制式:${res.formatValue}`)
                    }
                } as CustomScanOptions)
            }
        }
    }
</script>

<style>
    .content {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }

    .logo {
        height: 200rpx;
        width: 200rpx;
        margin-top: 200rpx;
        margin-left: auto;
        margin-right: auto;
        margin-bottom: 50rpx;
    }

    .text-area {
        display: flex;
        justify-content: center;
        flex-direction: column;
        align-items: center;
    }

    .title {
        font-size: 36rpx;
        color: #8f8f94;
    }
</style>

uniapp示例代码

<template>
    <view class="content">
        <image class="logo" :src="imageResult"></image>
        <view class="text-area">
            <text class="title" @click="scan()">扫码</text>
            <view style="display: flex;flex-direction: row;">
                <text class="title" style="margin: 40rpx 20rpx;" @click="multiCodeScannAction('back')">扫多码(后置)</text>
                <text class="title" style="margin: 40rpx 20rpx;" @click="multiCodeScannAction('front')">前置扫码</text>
            </view>
            <view style="display: flex;flex-direction: row;">
                <text class="title" style="margin: 40rpx 0;" @click="customScanAction(true)">自定义连续扫码</text>
                <text class="title" style="margin: 40rpx 40rpx;" @click="customScanAction(false)">自定义非连续扫码</text>
            </view>
            <text class="title" @click="componentAction()">半屏扫码</text>
            <text class="title" style="margin: 40rpx 0;" @click="generatingCodeAction()">生成码</text>
            <!-- 图片识码:从相册选图后识别(也可传网络图 URL / base64,见 decodeImageAction 注释) -->
            <view class="shibie_bg" style="display: flex;align-items: center;justify-content: space-between;">
                <text class="title" style="margin: 40rpx 10rpx;" @click="decodeImageFromHttp()">网络图片识别</text>
                <text class="title" style="margin: 40rpx 10rpx;" @click="decodeImageFromBase64()">Base64识别</text>
                <text class="title" style="margin: 40rpx 10rpx;" @click="decodeImageFromLocal()">本地图片识别</text>
            </view>
            <text style="margin-top: 100rpx;" class="title">扫码结果:{{title}}</text>

            <view @click="deletePathFileAction()"
                style="margin-top: 100rpx;background-color: burlywood;padding: 10rpx;">删除指定路径图片
            </view>
        </view>
    </view>
</template>

<script>
    // 导入要使用的插件
    import {
        scanAction,
        generatingCode,
        deletePathFile,
        multiCodeScann, //多码扫描
        customScan,
        decodeImage //图片识码(本地路径 / 网络URL / base64)
    } from "@/uni_modules/yt-uts-hwscan";
    export default {
        data() {
            return {
                title: 'Hello',
                imageResult: "/static/logo.png",
                httpImageUrl:"https://img-cdn-tx.dcloud.net.cn/stream/plugin_screens/ce720a60-ccd4-11ef-8d27-c321214806e1_0.png/webp?&v=1755831011",
                base64Str: "data:image/png;base64,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"
            }
        },
        onLoad() {

        },
        methods: {

            scan() {
                scanAction({
                    params: {
                        album: true,
                        scanTypes: [],//"QR", "EAN-13", "Aztec"
                        multiMode: true //鸿蒙端有效,是否支持多码
                    },
                    success: (res => {
                        console.log(res)
                        this.title = res.result
                    })
                })
            },

            generatingCodeAction() {
                // 调用同步方法示例
                generatingCode({
                    params: {
                        width: 300,
                        height: 300,
                        codeContent: '6932607220526',
                        formatValue: 'Aztec',
                    },
                    success: (RES => {
                        this.imageResult = RES.filePath
                    })
                })
            },
            deletePathFileAction() {
                // if (this.imageResult === "/static/logo.png") return;
                deletePathFile({
                    path: this.imageResult,
                    resultBackcall: (res => {
                        if (res) {
                            uni.showToast({
                                title: '删除成功',
                                icon: "none"
                            })
                        } else {
                            uni.showToast({
                                title: '删除失败',
                                icon: "none"
                            })
                        }
                    })
                })
            },
            multiCodeScannAction(cameraFacing) {
                multiCodeScann({
                    // 由页面上的前置/后置按钮分别传入 'front' 或 'back'
                    cameraFacing: cameraFacing,
                    album: true, //是否显示选相册按钮
                    isSelectOne: true, //后置默认true;前置固定false,此配置对前置无效
                    scanTitle: "多码扫描", //***导航标题
                    mulitiCodeMes: "扫描到多码请选择一个", //多码选一时提示文案
                    scanTypes: ["EAN-8", "EAN-13",
                        "QR"
                    ], //支持码制式集合不传或传[]标识支持识别以下所有码制式 'EAN-8' | 'EAN-13' | 'UPC-A' | 'UPC-E' | 'Codabar' | 'Code39' | 'Code93' | 'Code128' | 'ITF14' | 'QR' | 'DataMatrix' | 'PDF417' | 'Aztec' | 'Other'
                    isSound: true, //扫描震动与音效
                    scanResultHandler: (res) => {
                        console.log(res)
                    }
                })
            },
            //自定义扫码
            customScanAction(isContinue) {
                customScan({
                    album: true,
                    scanTypes: ["QR", "EAN-13", "Aztec"],
                    scanContinue: isContinue,
                    scanInterval: 3,
                    showLightBtn: true,
                    scanTitle: '自定义扫码11',
                    isSound: true,
                    scanResultHandler: (res) => {
                        this.title = res.code ?? ''
                        console.log(`扫描结果:${res.code} 识别码制式:${res.formatValue}`)
                    }
                })
            },
            componentAction() {
                uni.navigateTo({
                    url: '/pages/index/scan'
                })
            },
            /**
             * 网络图片识别
             * 当前仅 iOS 已实现;Android / Harmony 为占位
             */
            decodeImageFromHttp() {

                this.decodeImageAction(this.httpImageUrl);
            },
            /**
             * 本地图片识别
             * 当前仅 iOS 已实现;Android / Harmony 为占位
             */
            decodeImageFromLocal() {

                this.decodeImageAction(this.imageResult);
            },
            /**
             * Base64图片识别
             * 当前仅 iOS 已实现;Android / Harmony 为占位
             */
            decodeImageFromBase64() {

                this.decodeImageAction(this.base64Str);
            },
            /**
             * 图片识码调用示例
             * @param {string} imageSource 支持三种形式:
             * 1) 本地路径:如 chooseImage 返回的 tempFilePath、_doc/xxx.png、file://...
             * 2) 网络图片:https://xxx.com/qr.png(需可访问,建议 HTTPS)
             * 3) base64:纯 base64,或带前缀 data:image/png;base64,xxxx
             */
            decodeImageAction(imageSource) {
                console.log(imageSource);
                decodeImage({
                    params: {
                        // 必填:本地路径 / 网络 URL / base64
                        image: imageSource,
                        // 可选:限制识别的码制式,不传则识别全部
                        scanTypes: [],
                        // 可选:是否多码识别,默认 false;为 true 时结果看 res.results
                        multiMode: false
                    },
                    success: (res) => {
                        // res.result:码内容;res.formatValue:码制式;res.sceneType:场景类型
                        // multiMode 为 true 时,res.results 为多码字符串数组
                        console.log('图片识别成功', res)
                        this.title = res.result || (res.results && res.results.join(',')) || ''
                        uni.showToast({
                            title: '识别成功',
                            icon: 'none'
                        })
                    },
                    fail: (err) => {
                        // 9010001:图片为空或加载失败;9010002:图中未识别到码
                        console.log('图片识别失败', err)
                        uni.showToast({
                            title: err.errMsg || '识别失败',
                            icon: 'none'
                        })
                    },
                    complete: (res) => {
                        console.log('图片识别结束', res)
                    }
                })

                // ---------- 其他传参写法参考(不要同时执行,仅作注释示例) ----------
                // 1. 网络图片
                // this.decodeImageAction('https://example.com/qrcode.png')
                //
                // 2. base64(可带 data:image 前缀)
                // this.decodeImageAction('data:image/png;base64,iVBORw0KGgo...')
                // this.decodeImageAction('iVBORw0KGgo...') // 裸 base64 亦可
            }
        },
    }
</script>

<style>
    .content {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }

    .logo {
        height: 200rpx;
        width: 200rpx;
        margin-top: 200rpx;
        margin-left: auto;
        margin-right: auto;
        margin-bottom: 50rpx;
    }

    .text-area {
        display: flex;
        justify-content: center;
        flex-direction: column;
        align-items: center;
    }

    .title {
        font-size: 36rpx;
        color: #8f8f94;
    }
</style>

更多好用插件推荐

隐私、权限声明

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

相机、相册、文件读写

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

插件不采集任何数据

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

无