H5 Web网页实现扫一扫识别解析二维码,就现在方法的npm包就能实现,在这个过程中使用过html5-qrcode 和 vue3-qr-reader。
1、html5-qrcode的使用
感觉html5-qrcode有点小坑,在使用的时候识别不成功还总是进入到错误回调中出现类似NotFoundException: No MultiFormat Readers were able to detect the ....的错误,后面去到官网GitHub上看到有人说是版本问题,降到指定版本之后,一开始没有问题也可以识别了,奇怪的是,过一个星期直接噶了😭。。。(感觉不是很稳定,如果有不同见解可以交流一下)
html5-qrcode 的具体使用参考html5-qrcode
2、vue3-qr-reader的使用
vue3-qr-reader 是继 html5-qrcode 找到的第二种方案,这个相对来说比较稳定使用方式简单:
1、vue3项目中下载vue3-qr-reader包
npm install vue3-qr-reader
// 或者
npm i vue3-qr-reader
2、在项目中引用需要使用的组件,在页面t使用组件
<template>
<van-button @click="openQrcode" color="rgba(0, 0, 0, 0.3)"
style="border-color: rgba(255, 255, 255, 0.4)">扫一扫</van-button>
<-- 扫码页面内容 !-->
<div class="reader-box" v-if="isScaning">
<div class="line"></div>
<qr-stream @decode="onDecode" class="mb">
<div class="frame" style="color: red;"></div>
</qr-stream>
<div class="desc">扫描激活二维码</div>
<van-button @click="closeQrcode" color="rgba(0, 0, 0, 0.3)"
style="border-color: rgba(255, 255, 255, 0.4)">返回</van-button>
</div>
</template>
<script setup>
// 引入依赖
import { QrStream } from "vue3-qr-reader"
// ...
const isScaning = ref(false)
// 开启扫码
const openQrcode = ()=>{
isScaning.value = true
}
// 关闭扫码
const closeQrcode = ()=> {
isScaning.value = false
}
// 处理扫码成功后相关的业务内容
const onDecode = (data)=>{
try{
// data 为扫码结果 对data做相关处理进行下一步操作
}catch(err){
closeQrcode()
showNotify({
type:'danger',
message:'扫码失败,请联系管理员'
})
}
}
</script>
/* 相关样式 */
.reader-box {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.9);
z-index: 999;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.reader-box .desc {
position: fixed;
bottom: 140px;
font-family: PingFang SC, PingFang SC;
font-weight: bold;
font-size: 15px;
color: #ffffff;
margin-top: 16px;
}
.reader-box .van-button {
position: absolute;
bottom: 70px;
width: 90%;
border: 1px solid #fff;
}
.line {
position: absolute;
top: 180px;
width: 100%;
animation: radar-beam 2s infinite;
animation-timing-function: cubic-bezier(0.53, 0, 0.43, 0.99);
animation-delay: 1.4s;
z-index: 9999;
height: 130px;
border-bottom: 1px solid #4b66d0;
background: linear-gradient(to top, #4b66d0, transparent);
}
@keyframes radar-beam {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(90%);
}
}
最终实现效果如下
注意:因为获取摄像头权限,需要网页是https的,所以在本地调试的话要开启https,开启https的方式,可以参考这个大佬的方式本地localhost开启https通过软件及命令生成证书,并将证书放入到vue项目中,在vite.config.js的配置中加入并保存即可
import vue from '@vitejs/plugin-vue';
import { defineConfig, loadEnv } from 'vite';
import Components from 'unplugin-vue-components/vite';
import { VantResolver } from 'unplugin-vue-components/resolvers';
const fs = require('fs');
export default ({ mode }) =>
defineConfig({
plugins: [
vue(),
Components({
resolvers: [VantResolver()],
}),
],
css: {
postcss: {
plugins: [
require('postcss-pxtorem')({
rootValue: 50,
propList: ['*'],
selectorBlackList: ['.van-'],
}),
],
},
},
base: './',
server: {
host: '0.0.0.0',
// port: import.meta.VITE_PORT,
port: loadEnv(mode, process.cwd()).VITE_PORT,
// open: import.meta.VITE_OPEN,
proxy: {
'/api': {
target: 'https://xxx.com/',
ws: true,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
https: {
key: fs.readFileSync('public/127.0.0.1-key.pem'),
cert: fs.readFileSync('public/127.0.0.1.pem'),
},
},
minify: 'esbuild',
sourcemap: false,
});