zxing 实现扫描二维码获取信息

首先要安装这两个依赖

vueuse/nuxt
zxing/library
<script setup lang="ts">
const validNum = (val:any) => !(val.length === 0 || val ===''); // 设备序列号校验
const model = defineModel<any>()
const isScan = ref(false)
let codeReader: any
const cameraId = ref<any>()
const {videoInputs: cameras} = useDevicesList()
const show = ref(false);
const emit = defineEmits(["submit"])
watch(()=>cameras.value,(val)=>{
    if(val.length){
        cameraId.value=cameras.value[0].deviceId
    }
})
function handleTxt(txt:any){
    if(txt){
        if(txt.indexOf(';')){
            model.value = txt.split(';')[0]
        }
        else{
            model.value = txt
        }
    }
    show.value = false;
    emit("submit", model.value )
}
function  clearValue(){
    model.value = ''
}
onUnmounted(()=>{
    if(isScan.value){
        codeReader.reset()
        isScan.value = false
    }
})

const updatainput=useDebounceFn((val:any)=>{
    emit("submit", val )
}, 1000)

function btnScan() {
    if (isScan.value) {
        codeReader.reset()
        isScan.value = false
        return
    }
    navigator.mediaDevices.getUserMedia({ video: true })
        .then(stream => {
            // 用户授权了相机权限,可以进行后续操作
            show.value = true;
            import("@zxing/library").then(ZXing => {
                console.log(ZXing)
                codeReader = new ZXing.BrowserMultiFormatReader()
                isScan.value = true
                cameraId.value=null
                codeReader.listVideoInputDevices().then((videoInputDevices:any)=>{
                    //videoInputDevices 设备摄像头参数数组
                    cameraId.value = videoInputDevices[0].deviceId  //调用摄像头id
                })
                codeReader.decodeFromVideoDevice(cameraId.value, 'video', (result:any, err:any) => {
                    if (result) {
                        handleTxt(result.text);
                        isScan.value = false
                        codeReader.reset()
                    }
                    if (err && !(err instanceof ZXing.NotFoundException)) {
                        // 非 NotFound 错误
                        console.error('Error:', err);
                    }
                });
            })
        })
        .catch(err => {
            // 处理错误,可能是因为权限被拒绝
            console.log('获取相机权限失败:', err);
        });
}
defineExpose({
    clearValue
});
</script>

<template>
    <van-field @update:model-value="updatainput"  :rules="[{validator: validNum, message: '请输入设备序列号'}]" required label="设备序列号" v-bind="$attrs" v-model="model" placeholder="请输入设备序列号" clearable>
        <template #right-icon>
            <span  class="cursor-pointer flex justify-center gap-2">
                <u-icon  title="从摄像头扫描" @click.stop="btnScan" size="24" name="i-heroicons-qr-code"></u-icon>
            </span>
        </template>
    </van-field>
    <van-popup v-model:show="show" :style="{height:'60%',width:'100%'}">
        <video ref="video" autoplay id="video"></video>
    </van-popup>
</template>

<style scoped>

</style>

测试只能在https

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值