Vue3使用vue-qrcode-reader實現掃碼綁定設備功能(推薦)
更新時間:2024年10月21日 10:02:55 作者:魚是一只魚啊
本文介紹了在Vue3中使用vue-qrcode-reader版本5.5.7來實現移動端的掃碼綁定設備功能,用戶通過掃描二維碼自動獲取設備序列號,并填充到添加設備界面,完成設備綁定的全過程,包含ScanCode.vue和DeviceAdd.vue兩個主要界面的實現方式
需求描述
移動端進入網站后,登錄網站進入設備管理界面。點擊添加設備,可以選擇直接添加或者掃一掃。點擊掃一掃進行掃描二維碼獲取設備序列號自動填充到添加設備界面的序列號輸入框中。然后點擊完成進行設備綁定。
安裝vue-qrcode-reader 這里使用的版本是5.5.7
npm install vue-qrcode-reader --save
掃一掃界面ScanCode.vue
<template> <div class="block-main"> <div class="head-wrap"> <img src="../../assets/images/mobile/icon-arrow-left.png" class="btn-back" @click="goback" /> <span class="title">掃一掃</span> </div> <div class="qr-container"> <qrcode-stream @detect="onDecode" @camera-on="onCameraReady" @error="onError" /> </div> </div> </template> <script> import { reactive, ref, onMounted } from "vue"; import { useRouter } from "vue-router"; import { QrcodeStream } from "vue-qrcode-reader"; import { showToast } from "vant"; export default { components: { QrcodeStream, showToast, }, setup() { const testVice = reactive([]); const router = useRouter(); // 掃碼成功后的回調 const onDecode = (detectedCodes) => { if (detectedCodes.length > 0) { // 跳轉到添加設備頁面并傳遞設備編號 let deviceCode = detectedCodes[0].rawValue; router.replace({ path: "/deviceadd", query: { deviceCode }, }); } else { showToast("掃碼失敗"); } }; const onCameraReady = (res) => { console.log("攝像頭準備好了"); }; const onError = (error) => { if (error.name === "NotAllowedError") { // user denied camera access permission showToast("用戶拒絕相機訪問權限"); } else if (error.name === "NotFoundError") { // no suitable camera device installed showToast("未安裝合適的攝像設備"); } else if (error.name === "NotSupportedError") { // page is not served over HTTPS (or localhost) showToast("當前網頁沒有通過 HTTPS 或 localhost 安全協議提供服務"); } else if (error.name === "NotReadableError") { // maybe camera is already in use showToast("相機被占用了)"); } else if (error.name === "OverconstrainedError") { // did you request the front camera although there is none? showToast("嘗試使用前置攝像頭)"); } else if (error.name === "StreamApiNotSupportedError") { showToast("瀏覽器似乎缺少功能)"); // browser seems to be lacking features } }; onMounted(() => { navigator.mediaDevices .enumerateDevices() .then((devices) => { devices.forEach((device) => { if (device.kind === "videoinput") { console.log( "Video input device: ", device.label, device.deviceId ); } }); }) .catch((error) => { console.error("Error enumerating devices: ", error); showToast("Error enumerating devices"); }); }); const goback = () => { router.go(-1); }; return { testVice, onCameraReady, goback, onDecode, onError, }; }, }; </script> <style lang="scss" scoped> .block-main { height: 100%; background: #fff; overflow: hidden; font-size: 16px; .head-wrap { height: 0.96rem; background: #31be7c; font-family: Microsoft YaHei UI; font-weight: 400; color: #fff; display: flex; align-items: center; position: fixed; left: 0; right: 0; .btn-back { margin-left: 0.4rem; width: 0.22rem; height: 0.38rem; } .title { font-size: 0.36rem; text-align: center; flex: 1; } } .qr-container { display: flex; justify-content: center; align-items: center; height: calc(100vh - 0.96rem); // 減去頭部的高度 margin-top: 0.96rem; } } </style>
添加設備界面DeviceAdd.vue
<template> <div class="block-main"> <div class="head-wrap"> <a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" class="btn-cancel" @click="goBack">取消</a> <span class="title"></span> <a href="javascript:void(0)" rel="external nofollow" rel="external nofollow" class="btn-sure" @click="deviceReg">完成</a> </div> <div class="input-wrap" @click="showDeviceType"> <span class="input">{{ deviceInfo.devtypeName }}</span> <img src="../../assets/images/mobile/icon-arrow-right.png" class="icon-arrow" /> </div> <div class="input-wrap"> <input type="text" class="input" v-model="deviceInfo.devsn" placeholder="請輸入設備序列號" /> <img v-if="deviceInfo.devsn" src="../../assets/images/mobile/icon-close-gray.png" class="icon-close" @click="clearInput" /> </div> <div class="error-msg">{{ deviceInfo.devsn_error }}</div> <van-popup v-model:show="deviceTypeDialog" position="bottom"> <van-picker :columns="devTypes" v-model:value="deviceInfo.devtype" @cancel="deviceTypeDialog = false" @confirm="onConfirm" /> </van-popup> </div> </template> <script> import { ref, reactive, onMounted } from "vue"; import { useRoute,useRouter } from "vue-router"; import { Picker, Popup, showFailToast, showSuccessToast, showToast, showLoadingToast, } from "vant"; import { device_Reg } from "../../api/auth"; export default { components: { "van-picker": Picker, "van-popup": Popup, }, setup() { const route = useRoute(); const deviceTypeDialog = ref(false); const router = useRouter(); const devTypes = [ { value: 1, text: "設備類型1" }, { value: 2, text: "設備類型2" }, { value: 3, text: "設備類型3" }, ]; const deviceInfo = reactive({ devtype: null, devtypeName: "請選擇需要綁定的設備", devsn: "", devsn_error: "", }); const showDeviceType = () => { deviceTypeDialog.value = true; }; const clearInput = () => { deviceInfo.devsn = ""; deviceInfo.devsn_error = ""; }; const onConfirm = ({ selectedOptions }) => { deviceTypeDialog.value = false; deviceInfo.devtype = selectedOptions[0].value; deviceInfo.devtypeName = selectedOptions[0].text; }; const goBack = () => { router.go(-1); }; const deviceReg = async () => { if (deviceInfo.devtype == null) { deviceInfo.devsn_error = "請選擇設備類型"; return; } if (!deviceInfo.devsn) { deviceInfo.devsn_error = "請?zhí)顚懺O備序列號"; return; } const toast = showLoadingToast({ message: "數據提交中...", forbidClick: true, }); let response = await device_Reg({ devsn: deviceInfo.devsn, devtype: deviceInfo.devtype, }); if (response.isSuccess == true) { toast.close(); showSuccessToast("設備綁定成功"); setTimeout(() => { router.go(-1); }, 2000); } else { deviceInfo.devsn_error = response.message; toast.close(); } }; onMounted(() => { const scannedDeviceSn = route.query.deviceCode; if (scannedDeviceSn) { deviceInfo.devsn = scannedDeviceSn; } }); return { devTypes, deviceTypeDialog, deviceInfo, showDeviceType, clearInput, onConfirm, goBack, deviceReg, }; }, }; </script> <style lang="scss" scoped> .block-main { height: auto; overflow: hidden; .head-wrap { height: 0.96rem; background: #31be7c; font-family: Microsoft YaHei UI; font-weight: 400; color: #fff; display: flex; align-items: center; .btn-cancel { padding-left: 0.4rem; padding-right: 0.4rem; height: 0.96rem; line-height: 0.96rem; font-size: 0.36rem; color: #fff; } .title { font-size: 0.36rem; text-align: center; flex: 1; } .btn-sure { width: 1.15rem; height: 0.55rem; background: #ffffff; border-radius: 5px; font-size: 0.36rem; line-height: 0.55rem; margin-right: 0.4rem; margin-left: 0.4rem; color: #31be7c; } } .input-wrap { height: 1.2rem; line-height: 1.2rem; border-bottom: 1px solid #ced6d2; display: flex; align-items: center; .input { flex: 1; margin-left: 0.58rem; font-size: 0.3rem; width: 0px; border-style: none; outline: none; height: 1rem; text-align: left; } .icon-close { width: 0.36rem; height: 0.36rem; margin-right: 0.4rem; margin-left: 0.4rem; } .icon-arrow { width: 0.2rem; height: 0.3rem; margin-left: 0.04rem; margin-right: 0.4rem; margin-left: 0.4rem; } } .error-msg { padding-left: 0.58rem; margin-top: 0.19rem; font-size: 0.24rem; color: #ff6c00; padding-right: 0.58rem; text-align: left; line-height: 0.24rem; } } </style>
效果圖
到此這篇關于Vue3使用vue-qrcode-reader實現掃碼綁定設備功能的文章就介紹到這了,更多相關Vue3掃碼綁定設備內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!