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>

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

四、总结

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

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

相关推荐
Sheldon一蓑烟雨任平生1 小时前
Vue3 插件(可选独立模块复用)
vue.js·vue3·插件·vue3 插件·可选独立模块·插件使用方式·插件中的依赖注入
鱼与宇2 小时前
苍穹外卖-VUE
前端·javascript·vue.js
用户47949283569152 小时前
Safari 中文输入法的诡异 Bug:为什么输入 @ 会变成 @@? ## 开头 做 @ 提及功能的时候,测试同学用 Safari 测出了个奇怪的问题
前端·javascript·浏览器
裴嘉靖3 小时前
Vue 生成 PDF 完整教程
前端·vue.js·pdf
毕设小屋vx ylw2824263 小时前
Java开发、Java Web应用、前端技术及Vue项目
java·前端·vue.js
冴羽4 小时前
今日苹果 App Store 前端源码泄露,赶紧 fork 一份看看
前端·javascript·typescript
蒜香拿铁4 小时前
Angular【router路由】
前端·javascript·angular.js
时间的情敌4 小时前
Vite 大型项目优化方案
vue.js
西洼工作室4 小时前
高效管理搜索历史:Vue持久化实践
前端·javascript·vue.js
樱花开了几轉5 小时前
element ui下拉框踩坑
开发语言·javascript·ui