vue实现移动端扫一扫功能(带样式)

前言:

最近在做一个vue2的项目,其中有个需求是,通过扫一扫功能,扫二维码进入获取到对应的code,根据code值获取接口数据。

在移动端开发中,扫一扫功能是一个非常实用的特性。它可以帮助用户快速获取信息、进行支付、添加好友等操作。而 Vue 作为一种流行的前端框架,为我们实现移动端扫一扫功能提供了强大的支持。

本文将详细介绍如何使用 Vue 实现移动端扫一扫功能,并为其添加个性化的样式。

一、需要实现的效果图

二、背景

我这边的需求是,需要在移动端使用扫一扫功能进行物品的盘点。由于有的地方环境比较暗,所以要兼具"可开关手机手电筒"的功能,即上图中的"轻触点亮"。

本文主要介绍:

  • 运用 vue-qrcode-reader 插件实现扫一扫功能;
  • 实现打开手电筒功能;
  • 按照上图中的设计稿实现样式,并且中间蓝色短线是上下扫描的视觉效果。

三、下载并安装插件

  1. 可参考vue-qrcode-reader官网
  2. 在项目install这个插件:
js 复制代码
npm install --save vue-qecode-reader

或者

js 复制代码
cnpm install --save vue-qrcode-reader
  1. 然后就可以在代码中引入了:
js 复制代码
import { QrcodeStream } from 'vue-qrcode-reader';

components: {
    QrcodeStream
},
  1. html中的结构可以这样写:

附上代码可直接复制:

html 复制代码
<template>
  <div class="saoma">
    <qrcode-stream
      :torch="torchActive"
      @decode="onDecode"
      @init="onInit"
      style="height: 100vh; width:100vw">
      <div>
        <div class="qr-scanner">
          <div class="box">
            <div class="line"></div>
            <div class="angle"></div>
            <div @click="openTorch" class="openTorch">
              <img src="@/assets/imgs/icon_torch.png" />
              <div>轻触点亮</div>
            </div>
          </div>
        </div>
      </div>
    </qrcode-stream>
  </div>
</template>

API介绍可参考vue-qrcode-reader API介绍

  1. js中主要包含两个通用的事件和一个"轻触点亮"的事件:

注:

我这边的这个扫码页面,会根据情况分别跳转到两个页面,所以做了区分。

实现打开手电筒的功能时,要先自定义一个变量torchActive,将初始值设置为false,同时要注意在onDecode方法中,要重置为false

下面将js的全部代码附上:

js 复制代码
<script>
import { QrcodeStream } from 'vue-qrcode-reader';

export default {
  props: {
    operationType: {
      type: String,
      default: '',
    },
  },
  components: {
    QrcodeStream
  },
  data() {
    return {
      result: '', // 扫码结果信息
      torchActive: false,
      error: '' // 错误信息
    }
  },
  methods: {
    // 打开手电筒
    openTorch() {
      switch (this.torchActive) {
        case true:
          this.torchActive = false;
          break;
        case false:
          this.torchActive = true;
          break;
      }
    },
    onDecode(result) {
      if (result) {
        this.torchActive = false;
        if (this.$route.query.id) {
          this.$router.push({
            path: `/sub-asset-details`,
            query: {
              taskId: this.$route.query.id,
              assetId: result,
            },
          });
        } else {
          this.$router.push({ path: `/home/${result}` });
        }
      } else {
        this.$toast('未获得扫码结果!');
      }
    },
    async onInit(promise) {
      try {
        await promise
      } catch (error) {
        console.log('error',error);
        if (error.name === 'NotAllowedError') {
          alert('您需要授予相机访问权限')
        } else if (error.name === 'NotFoundError') {
          alert('这个设备上没有摄像头')
        } else if (error.name === 'NotSupportedError') {
          this.$Message.warning('所需的安全上下文(HTTPS、本地主机)')
        } else if (error.name === 'NotReadableError') {
          this.$Message.warning('相机被占用')
        } else if (error.name === 'OverconstrainedError') {
        } else if (error.name === 'StreamApiNotSupportedError') {
          this.$Message.warning('此浏览器不支持流API')
        }else if(error.name === 'InsecureContextErroe'){
          this.$Message.warning('请在安全的情况下才访问摄像头')
        }
      }
    },
  }
}
</script>
  1. CSS可参考下面的代码,其中中间那条蓝色的短线是动态上线扫描的效果:

注:

  • 颜色可自定义(我这边的主色是蓝色,可根据自己项目调整);
  • 我的项目用的css语法是less,也可根据自己项目修改。
css 复制代码
<style lang="less" scoped>
.saoma {
  width: 100vw;
}
.qr-scanner {
  width: 100%;
  height: 100vh;
  position: relative;
  background-color: rgba(43, 37, 32, 0.4);
}
.qr-scanner .box {
  width: 448px;
  height: 448px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  overflow: hidden;
}
.qr-scanner .line {
  height: 100%;
  width: 304px;
  margin: auto;
  border-bottom: 6px solid;
  border-image-source: linear-gradient(90deg, rgba(78, 204, 254, 0) 0%, #4ECCFE 37%, #3F90FD 67%, rgba(63, 144, 253, 0) 100%);
  border-image-slice: 1;
  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: 6vw;
  height: 6vw;
  border: 8px solid transparent;
}
.qr-scanner .box:after,
.qr-scanner .box:before {
  top: 0;
  border-top-color: #3F90FD;
}
.qr-scanner .angle:after,
.qr-scanner .angle:before {
  bottom: 0;
  border-bottom-color: #3F90FD;
}
.qr-scanner .box:before,
.qr-scanner .angle:before {
  left: 0;
  border-left-color: #3F90FD;
}
.qr-scanner .box:after,
.qr-scanner .angle:after {
  right: 0;
  border-right-color: #3F90FD;
}
.openTorch {
  position: absolute;
  bottom: 20px;
  left: 44%;
  font-size: 20px;
  color: #fff;
  text-align: center;

  img {
    width: 30px;
    height: 40px;
    margin-bottom: 8px;
  }
}
@keyframes radar-beam {
  0% {
    transform: translateY(-100%);
  }
  100% {
    transform: translateY(0);
  }
}
</style>

这就是实现这个页面功能的全部代码了~

四、总结

读者可以通过本文介绍,根据自己的需求进行定制和扩展。无论是为了提高用户体验还是满足特定的业务需求,这个功能都能为你的移动端应用增添不少价值。

以上,希望对大家有帮助!

相关推荐
活宝小娜41 分钟前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点44 分钟前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow1 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o1 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
刚刚好ā2 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年3 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder3 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727573 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
会发光的猪。4 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js
天下代码客4 小时前
【vue】vue中.sync修饰符如何使用--详细代码对比
前端·javascript·vue.js