更新记录

1.0.15(2025-08-23)

  • 更新文档

1.0.14(2025-08-22)

  • 修复uniapp报错

1.0.13(2025-08-21)

  • 新增component方式
查看更多

平台兼容性

uni-app(4.43)

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

uni-app x(4.43)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 5.0 - - ×

特别提醒

  • 购买本插件前,请先试用、请先试用、请先试用,并充分自测确认满足需求之后再行购买。虚拟物品一旦购买之后无法退款;
  • 如有使用上的疑问、bug,可以进交流群联系作者;
  • 作者可承接各种插件定制;
  • 请在合法范围内使用,若使用本插件做非法开发,本方概不负责;
  • 结合文档和示例demo集成使用;
  • Android体验Demo安装包 https://www.pgyer.com/hwscanunix

插件使用文档

说明:支持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

扫码

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

多码扫描(仅iOS、Android有效)

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)
    }
} as MulitiCodeOptions) //uniapp/非ts项目去掉as MulitiCodeOptions
  • 多码扫描参数说明 参数是自定义的MulitiCodeOptions类型参数,ts/uts项目需加上 as MulitiCodeOptions 如上方示例代码
参数 值类型 说明
album bool 是否显示选相册按钮
isSelectOne bool 是否多选一,默认true
scanTitle String 导航标题
mulitiCodeMes String 多码选一时提示文案
scanTypes [String] 支持的码制式(数组中的值需为上表13种码制式中包含的值)
scanResultHandler function 扫描回调返回字符串数组

自定义扫码(仅iOS、Android有效)

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 扫码成功播放音效与震动
scanTypes [String] 支持的码制式(数组中的值需为上表13种码制式中包含的值)
scanTitle string 导航标题
scanResultHandler function 扫描回调

component方式集成(半屏/全屏扫码)

仅在uniapp/nvue页面和uniapp-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">
        <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: [] 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
            }
        },
        methods: {
            //相册识别
            alblue() {
                (this.$refs["hwscan"] as YtScanElement).albumRecognition()
            },
            //开关手电筒
            flashlightSwitch() {
                (this.$refs["hwscan"] as YtScanElement).switchFlashlight()
            },
            //扫码成功回调
            // #ifdef APP-IOS
            recognitionHandler(res) {
                let value = res.detail.code ?? "";
                let type = res.detail.formatValue ?? "";
                uni.showToast({
                    title: `扫描结果:${value}`,
                    icon: 'none'
                })
                console.log(`扫描结果:${value} ---- 码制式:${type}`)
            },
            // #endif
            // #ifdef APP-ANDROID
            recognitionHandler(res : hwScan.CustomScanResult) {
                let value = res.code ?? "";
                let type = res.formatValue ?? "";
                uni.showToast({
                    title: `扫描结果:${value}`,
                    icon: 'none'
                })
                console.log(`扫描结果:${value} ---- 码制式:${type}`)
            },
            // #endif

            //相册识别失败回调
            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
        }
    }
</script>

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

    .scan-view {
        width: 750rpx;
        flex: 1;
    }

    .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>

构建码使用说明

// 调用同步方法示例
generatingCode({
    params: {
        width: 400,
        height: 400,
        codeContent: '6932607220526',
        formatValue: 'QR',
        backgroundColor: "#ff00ff",//码图背景色,默认背景色为白色,仅Android有效
        bitMargin: 1,//设置码图边框宽度,默认码图边框宽度为1,仅Android有效
        bimapColor: "#00ff00",//码图颜色,默认码图颜色为黑色,仅Android有效
        logo: "/static/logo.png"//二维码中间logo,仅Android有效
    },
    success: (RES => {
        this.imageResult = RES.filePath
    })
})

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

  • 参数说明
参数 值类型 说明
width int 宽度
height int 高度
codeContent String 内容
formatValue String 码制式(参照上方scanType表)
filePath String 码存储路径
backgroundColor String(HEX字符串) 码图背景色,默认背景色为白色,仅Android有效
bimapColor String(HEX字符串) 码图颜色,默认码图颜色为黑色,仅Android有效
logo String 二维码中间logo路径,仅Android有效
bitMargin number 设置码图边框宽度,默认码图边框宽度为1,仅Android有效

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

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

鸿蒙端没有真机不确定能不能用,代码已经写了

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,
        ScanFormatTypeCode, //码制式
        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"]
                    } 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>
            <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,
        ScanFormatTypeCode, //码制式
        deletePathFile,
        multiCodeScann,//多码扫描
        CustomScanOptions,
        customScan
    } from "@/uni_modules/yt-uts-hwscan";
    export default {
        data() {
            return {
                title: 'Hello',
                imageResult: "/static/logo.png"
            }
        },
        onLoad() {

        },
        methods: {

            scan() {
                scanAction({
                    params: {
                        album: true,
                        scanTypes: ["QR", "EAN-13", "Aztec"]
                    },
                    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() {
               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)
             }
            })
        },
        //自定义扫码
            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}`)
                    }
                })
            }
    }
</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. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: