首页 > 其他分享 >vue3+vite+ts+vue3-qr-reader实现移动端h5+pc端调起摄像头核销二维码

vue3+vite+ts+vue3-qr-reader实现移动端h5+pc端调起摄像头核销二维码

时间:2024-10-15 17:45:05浏览次数:5  
标签:qr const scanner ts rgba vue3 transparent 255

1、首先我们看示例图:
  h5:
pc:

 

 

 

2、我们开始做第一步就是装依赖:yarn add vue3-qr-reader 或者 npm install vue3-qr-reader
  我记得装完后还需要装一个 yarn add -D sass 

 

3、封装一个组件公用:组件位置你们自己定
  我写在了components/QrScanner/index
  这里面我用到了 element-plus 的icon 想用的可以安装对应依赖 https://s-test.belle.cn/zh-CN/
<template>
    <div>
      <QrStream
        :style="scannerStyle"
        @decode="handleDecode"
        @init="handleInit"
        @error="handleError"
      >
        <template v-if="showCloseButton">
          <div class="qr-scanner-container">
            <!-- <div class="close-view dis-center" @click="closeScanner">X</div> -->
            <el-icon @click="closeScanner" class="close-view dis-center"><CircleClose /></el-icon>
            <div class="qr-scanner">
              <div class="box">
                <div class="line"></div>
                <div class="angle"></div>
              </div>
            </div>
          </div>
        </template>
      </QrStream>
    </div>
  </template>
 
  <script setup>
  import { ref, defineExpose } from 'vue'
  import { QrStream } from 'vue3-qr-reader'
  import { CircleClose } from '@element-plus/icons-vue'
 
  const emit = defineEmits(['decode','close'])
 
  const scannerStyle = {
    position: 'fixed',
    top: 0,
    left: 0,
    width: '100vw',
    height: '100vh',
    zIndex: 9999,
  }
 
  const showCloseButton = ref(false)
 
  const qrcodeData = ref(null)
 
  const handleDecode = (data) => {
    console.log('Decoded data:', data)
    emit('decode', data)
    qrcodeData.value = data
   
  }
 
  const closeScanner = () => {
    emit('close')
  }
 
  const handleInit = async (promise) => {
    try {
      const { capabilities } = await promise
      console.log('Camera capabilities:', capabilities)
      showCloseButton.value = true
    } catch (error) {
      handleError(error)
     
    }
  }
 
  const handleError = (error) => {
    const errorMessages = {
      NotAllowedError: '您需要授予相机访问权限',
      NotFoundError: '这个设备上没有摄像头',
      NotSupportedError: '所需的安全上下文(HTTPS、本地主机)',
      NotReadableError: '相机被占用',
      OverconstrainedError: '安装摄像头不合适',
      StreamApiNotSupportedError: '此浏览器不支持流API',
      InsecureContextError: '仅允许在安全上下文中访问摄像机。使用HTTPS或本地主机,而不是HTTP。',
    }
 
    const message = errorMessages[error.name] || 'ERROR: 摄像头错误'
    message.error(message)
    console.error(message)
  }
 
  defineExpose({ qrcodeData })
  </script>
 
  <style scoped lang="scss">
  .qr-scanner-container {
    position: relative;
    width: 100%;
    height: 100%;
 
    .close-view {
        position: absolute;
        top: 20px;
        right: 20px;
        font-size: 40px;
        color: #FFFFFF;
        z-index: 1000000;
    }
  }
 
  .qr-scanner {
    background-image: linear-gradient(
        0deg,
        transparent 24%,
        rgba(32, 255, 77, 0.1) 25%,
        rgba(32, 255, 77, 0.1) 26%,
        transparent 27%,
        transparent 74%,
        rgba(32, 255, 77, 0.1) 75%,
        rgba(32, 255, 77, 0.1) 76%,
        transparent 77%,
        transparent
      ),
      linear-gradient(
        90deg,
        transparent 24%,
        rgba(32, 255, 77, 0.1) 25%,
        rgba(32, 255, 77, 0.1) 26%,
        transparent 27%,
        transparent 74%,
        rgba(32, 255, 77, 0.1) 75%,
        rgba(32, 255, 77, 0.1) 76%,
        transparent 77%,
        transparent
      );
    background-size: 3rem 3rem;
    background-position: -1rem -1rem;
    width: 100%;
    /* height: 100%; */
    height: 100vh;
    position: relative;
    ">#1110;
 
    /* */
  }
 
  .qr-scanner .box {
    width: 213px;
    height: 213px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    overflow: hidden;
    border: 0.1rem solid rgba(0, 255, 51, 0.2);
    /* background: url('http://resource.beige.world/imgs/gongconghao.png') no-repeat center center; */
  }
 
  .qr-scanner .line {
    height: calc(100% - 2px);
    width: 100%;
    background: linear-gradient(180deg, rgba(0, 255, 51, 0) 43%, #00ff33 211%);
    border-bottom: 3px solid #00ff33;
    transform: translateY(-100%);
    animation: radar-beam 2s infinite alternate;
    animation-timing-function: cubic-bezier(0.53, 0, 0.43, 0.99);
    animation-delay: 1.4s;
  }
 
  .qr-scanner .box:after,
  .qr-scanner .box:before,
  .qr-scanner .angle:after,
  .qr-scanner .angle:before {
    content: '';
    display: block;
    position: absolute;
    width: 3vw;
    height: 3vw;
 
    border: 0.2rem solid transparent;
  }
 
  .qr-scanner .box:after,
  .qr-scanner .box:before {
    top: 0;
    border-top-color: #00ff33;
  }
 
  .qr-scanner .angle:after,
  .qr-scanner .angle:before {
    bottom: 0;
    border-bottom-color: #00ff33;
  }
 
  .qr-scanner .box:before,
  .qr-scanner .angle:before {
    left: 0;
    border-left-color: #00ff33;
  }
 
  .qr-scanner .box:after,
  .qr-scanner .angle:after {
    right: 0;
    border-right-color: #00ff33;
  }
 
  @keyframes radar-beam {
    0% {
      transform: translateY(-100%);
    }
 
    100% {
      transform: translateY(0);
    }
  }
  </style>
 
 

  

4、显示的页面里使用:
<template>
    <QrScanner v-if="showQrCodeReader" @decode="onDecodeHandler" @close="qrReaderClose"></QrScanner>
</template>
<script setup>
import QrScanner from "@/components/QrScanner/index.vue"
import { ref, reactive, onMounted, onUnmounted, nextTick, getCurrentInstance, watchEffect } from "vue";

const showQrCodeReader = ref(false)
const paymentData = reactive({
  orderId: '',
  authCode: '',
  drawer: false
})
const qrcodeDetail = ref({})

/*
data 的值为下列地址为扫描二维码后得到的数据
 http://localhost:8000?content=p6hi1rQzu%2B956WKJ%2BomXQVxuvddBBgPdVxKvDXBiIoO9HhE%2FLdR0pyikGRrAYjMGbcraGZjravDGcAjYdDSu9Q%3D%3D

使用getContentFromUrl() 获取content的值
*/
const onDecodeHandler = (data) => {
  paymentData.authCode = getContentFromUrl(data)
  showQrCodeReader.value = false
  
}
const qrReaderClose = () => {
  showQrCodeReader.value = false
}
const getContentFromUrl = (url) => {
  const urlObj = new URL(url);
  const content = urlObj.searchParams.get('content');
  return content;
}

</script>

  

 

标签:qr,const,scanner,ts,rgba,vue3,transparent,255
From: https://www.cnblogs.com/wasbg/p/18468062

相关文章

  • vue下安装 v-charts
     默认安装报错误,如下: 下面修改源重新安装 1.清空镜像npmcacheclean--force 2.查看当前的镜像npmconfiggetregistry 3.设置镜像:npmconfigsetregistryhttps://registry.npmmirror.com 4.安装C:\Users\huangxueliang\PycharmProjects\vuetest>npmiv......
  • Kubernets 生成永不过期的token
    [root@k8s-master-01~]#kubeadmtokencreate--ttl0m3g8ci.usn0m7xw6xp266xe[root@k8s-master-01~]#kubeadmtokencreate--ttl0c5g3ke.7tcrrnkq6nrov9gk[root@k8s-master-01~]#kubeadmtokenlistTOKENTTLEXPIRESUSAGES......
  • 详解Python中的Requests会话管理
    在Python的网络编程中,requests库因其简洁的API和强大的功能而广受欢迎。它简化了HTTP请求的过程,使得开发者可以轻松地发送请求并处理响应。然而,requests库的真正强大之处在于其会话管理功能。通过会话管理,我们可以维护一个会话,在这个会话中发送多个请求,这样可以提高性能并......
  • 4. WebSockets
    4.WebSockets4.1.WebSocket介绍WebSocket协议RFC6455提供了一种标准化方法,可以通过单个TCP连接在Client端和服务器之间构建全双工双向通信通道。它是与HTTP不同的TCP协议,但旨在通过端口80和443在HTTP上工作,并允许重复使用现有的防火墙规则。WebSocket交互......
  • 在Vue3中使用vuex
    Vuex简介Vuex是Vue.js官方的状态管理库,帮助我们在中大型应用中集中管理组件间的共享状态。它通过state、getters、mutations和actions实现响应式数据管理Vuex核心概念State:全局状态,存储应用的核心数据。Getters:类似于组件中的计算属性,用于从state中派生出......
  • 在K8S中,Requests 和 Limits 如何影响 Pod 的调度?
    在Kubernetes中,Pod的调度过程受到资源请求(Requests)和资源限制(Limits)的直接影响。以下是这些参数如何影响Pod调度的详细说明:资源请求(Requests):资源请求定义了Pod中每个容器所需的最小资源量。在调度Pod时,Kubernetes调度器会寻找具有足够可用资源的节点来满足这些请求......
  • 某市驾驶培训监管服务平台 GreatSQL 数据库适配之旅
    某市驾驶培训监管服务平台GreatSQL数据库适配之旅一、项目背景某市驾培系统主要为社会公众提供驾培单位查询和学车报名,为相关合作单位提供某市驾培监管、某市驾培考核等功能。业务信息教练车培训过程视频信息、包括培训机构基本信息、教练员基本信息和学员个人等信息,其服务范......
  • jsp电脑配件销售网站的设计与实现qrl6o(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表用户,商品分类,商品品牌,商品信息开题报告内容一、课题名称电脑配件销售网站的设计与实现二、研究背景与意义随着互联网技术的快速发展,电子商务已成为现代商......
  • 神经网络之卷积篇:详解残差网络(ResNets)(Residual Networks (ResNets))
    详解残差网络ResNets是由残差块(Residualblock)构建的,首先解释一下什么是残差块。这是一个两层神经网络,在\(L\)层进行激活,得到\(a^{\left\lbrackl+1\right\rbrack}\),再次进行激活,两层之后得到\(a^{\left\lbrackl+2\right\rbrack}\)。计算过程是从\(a^{[l]}\)开始,首先进......
  • ITIL 4给ITSM建设带来哪些指导性意义
    ITIL4自2019年发布以来,对IT服务管理产生了巨大影响,其中作为ITIL4的关键内容,其指导原则体现了ITIL和服务管理的核心,支持所有类型和所有级别的成功实践和有效决策。今天我们就来对这些指导原则进行解释和分析。什么是指导原则最常见、最简单的使用方式,在作业里的脚本执行、文件分......