在新的项目中需要用到扫码功能,在网上找了好久,基本不能满足新项目的需求,下面是我总结出来的一个案例
我这里的 ui 用的是 vant 3
先看效果图
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b2428dbcabd848d68b7816c76bab5a8c.png#pic_center)
扫码成功后返回二维码中的数据或者跳转页面都可以
扫码前的准备
下载 vue-qrcode-reader
npm i vue-qrcode-reader
下载 vitejs/plugin-basic-ssl
npm i @vitejs/plugin-basic-ssl
实现扫码功能需要本地开启https访问模式,配置 vite.config.ts
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a964fd6eb32048ada00d1747e542bc8d.png#pic_center)
直接上代码
<template>
<div style="height: 100vh">
<qrcode-stream @detect="onDecode" @error="onInit" style="height: 100%">
<div>
<div class="qr-scanner">
<div>
<van-icon class="scanImg" @click="onClickLeft" name="arrow-left" />
</div>
<div class="box">
<div class="line"></div>
<div class="angle"></div>
</div>
<div class="txt">
将二维码/条码放入框内,即自动扫描
</div>
</div>
</div>
</qrcode-stream>
</div>
</template>
在这里说明一下为什么不用@decode方法而用@detect方法,因为在5.0以上的版本官方已经把@decode方法给删除了换成了@detect方法,5.0以下的版本请使用@decode,5.0以上的版本请使用@detect,原因可以自己去尝试。现在网上用的都不是最新版本,在这个地方导致我浪费了很多时间
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b368ea6bd06e4150bbad091fdc3a5d5e.png#pic_center)
查看vue-qrcode-reader相关版本可以在项目的 package.json 文件中查看,我这里vue-qrcode-reader的版本是5.5.6
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/5cb7834e52924b92a4af65e401ce035d.png#pic_center)
其他相关内容可以在下面的官方链接中查看
链接:vue-qrcode-reader官方链接
<script setup lang="ts">
import {QrcodeStream} from "vue-qrcode-reader";
import {ref} from "vue";
import {showSuccessToast} from "vant";
const dataList = ref('')
const result = ref(true)
const error = ref('')
const onDecode = (res: any) => {
dataList.value = res
result.value = false
console.log('你好',dataList.value)
showSuccessToast('扫描成功')
}
const onInit = async (promise: any) => {
console.log('初始化摄像头',promise)
try {
await promise
}catch (err: any) {
if (err.name === 'NotAllowedError') {
error.value = 'ERROR: 您需要授予相机访问权限';
} else if (err.name === 'NotFoundError') {
error.value = 'ERROR: 这个设备上没有摄像头';
} else if (err.name === 'NotSupportedError') {
error.value = 'ERROR: 所需的安全上下文(HTTPS、本地主机)';
} else if (err.name === 'NotReadableError') {
error.value = 'ERROR: 相机被占用';
} else if (err.name === 'OverconstrainedError') {
error.value = 'ERROR: 安装摄像头不合适';
} else if (err.name === 'StreamApiNotSupportedError') {
error.value = 'ERROR: 此浏览器不支持流API';
}
}
}
const onClickLeft = () => {
history.back();
}
</script>
<style scoped>
:deep(i.van-badge__wrapper.van-icon.van-icon-arrow-left.scanImg){
font-size: 40px;
color: white;
}
.scanImg{
margin-top: 30px;
margin-left: 10px;
}
.error {
font-weight: bold;
color: red;
}
.cameraMessage {
width: 100%;
height: 60px;
}
.qr-scanner {
background-size: 3rem 3rem;
background-position: -1rem -1rem;
width: 100%;
height: 100vh;
position: relative;
background-color: #1110;
}
.qr-scanner .box {
width: 213px;
height: 213px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
border: 1px solid #3aa5ff;
}
.qr-scanner .txt {
width: 100%;
height: 35px;
line-height: 35px;
font-size: 14px;
text-align: center;
margin: 0 auto;
position: absolute;
top: 70%;
left: 0;
}
.qr-scanner .myQrcode {
text-align: center;
color: #3aa5ff;
}
.qr-scanner .line {
height: calc(100% - 2px);
width: 100%;
background: linear-gradient(180deg, rgba(0, 255, 51, 0) 43%, #3aa5ff 211%);
border-bottom: 1px solid #3aa5ff;
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;
}
.qr-scanner .box:after,
.qr-scanner .box:before {
top: 0;
border-top-color: #3aa5ff;
}
.qr-scanner .angle:after,
.qr-scanner .angle:before {
bottom: 0;
border-bottom-color: #3aa5ff;
}
.qr-scanner .box:before,
.qr-scanner .angle:before {
left: 0;
border-left-color: #3aa5ff;
}
.qr-scanner .box:after,
.qr-scanner .angle:after {
right: 0;
border-right-color: #3aa5ff;
}
@keyframes radar-beam {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0);
}
}
</style>
扫码前记得给浏览器或者 app 授权摄像头权限