在UniApp的H5專案中,生成二維條碼和掃描二維條碼的操作處理

2022-09-21 15:00:45

在我們基於UniApp的H5專案中,需要生成一些二維條碼進行展示,另外也需要讓使用者可以掃碼進行一定的快捷操作,本篇隨筆介紹一下二維條碼的生成處理和基於H5的掃碼進行操作。二維條碼的生成,使用了JS檔案weapp-qrcode.js進行處理,而二維條碼掃碼則是基於一個第三方元件的方式進行支援的,最後通過統一入口來支援不同平臺的掃碼操作。

1、二維條碼的生成處理

二維條碼的生成,使用了JS檔案weapp-qrcode.js進行處理的。因此我們在頁面或者元件使用它的時候,需要引入JS檔案才能呼叫。

import qrCode from '@/libs/weapp-qrcode.js';

我們為二維條碼的展示,建立一個自定義元件,用來展示二維條碼資訊以及一些說明資訊,如下所示。

<view class="hidden-box">
    <!-- <view class="code-tit">二維條碼</view> -->
    <view class="qrcode-box">
        <tui-no-data v-if="!code" :fixed="false" imgUrl="/static/image/img_nodata.png">暫未生成二維條碼
        </tui-no-data>
        <view class="qrcode" v-else>
            <canvas :style="{ width: qrcode_w + 'px', height: qrcode_w + 'px' }" canvas-id="qrcode"
                id="qrcode"></canvas>
        </view>
    </view>
    <view class="explain" v-if="desc.length > 0">使用說明</view>
    <view class="explain-text" v-for="(items, index) in desc" :key="items">{{ items }}
    </view>
</view>

如果沒有生成二維條碼的所示,我們用一個空圖片代替,如下效果所示。

 二維條碼生成的時候,接收一個控制元件id,以及二維條碼的值,生成函數程式碼如下所示。

    // 二維條碼生成工具
    qrcode(text, canvasId) {
        // console.log(text, canvasId)
        new qrCode(canvasId, {
            text: text,
            width: this.qrcode_w,
            height: this.qrcode_w,
            colorDark: '#000000',
            colorLight: '#ffffff',
            correctLevel: qrCode.CorrectLevel.H
        });
    }

在新增一個方法對展示進行摺疊處理,那麼具體如下所示。

showDetail() {
    this.visible = !this.visible;
    if (this.visible) {
        setTimeout(() => {
            this.qrcode(this.code, 'qrcode');
        }, 60);
    }
},

在測試頁面中,匯入剛才的二維條碼自定義元件,然後以普通的元件一樣使用它即可。

<qrcode-info :code="entity.qrCode"></qrcode-info>

隨便弄一個二維條碼的值,生成二維條碼後的介面測試效果如下所示。

 

2、二維條碼的掃碼操作

我們知道,基於UniApp的程式中,內建有掃碼操作

uni.scanCode(OBJECT)

地址是:https://uniapp.dcloud.net.cn/api/system/barcode.html

不過該介面卻不能在H5中呼叫掃碼處理,

 如果需要在H5應用中掃碼,那麼需要另闢蹊徑,如果使用基於微信的SDK進行,還需要一系列的操作很麻煩,而且H5掃碼一般需要https的支援才能呼叫攝像頭的。

我在GitHub上搜尋了一些基於H5掃碼的專案,好像效果都不是很理想,估計是沒有找到好的案例。在不經意間,發現《H5呼叫攝像頭識別二維條碼》(需要https環境才能使用)效果挺好,就下來整合在專案中使用。

為了方便通用的掃碼處理,我們這裡定義了一個通用的掃碼頁面scan-qrcode.vue ,其他地方需要掃碼的,統一定位到該頁面處理即可。

在頁面程式碼中,我們引入上面的二維條碼掃描元件即可,如下程式碼所示。

<template>
    <view class="container">
        <get-qrcode @success='qrcodeSucess' @error="qrcodeError"></get-qrcode>
    </view>
</template>

<script>
    import getQrcode from '@/pages/components/GetQrcode/getQrcode.vue'
    export default {
        components: {
            getQrcode
        },

另外定義一個to引數,用來判斷頁面轉到那裡去的。

data() {
    return {
        to: '' //頁面帶過來的to地址
    }
},
onLoad(options) {
    this.to = options?.to;
}

同時定義兩個方法,一個是成功處理的,一個是出錯的提示的。

qrcodeSucess(data) {
    if (uni.$u.test.url(data)) {
        let url = data;
        console.log(url)
        if (url.indexOf('#') > 0) {
            let pageurl = url.split('#')[1];
            console.log(pageurl);
            //在頁面地址後增加一個to引數
            let toUrl = uni.$u.test.isEmpty(this.to) ? pageurl : (pageurl + `&to=${this.to}`)
            uni.navigateTo({
                url: toUrl
            })
        } else {
            uni.$u.toast("URL格式不符");
        }
    }
},
qrcodeError(err) {
    console.log(err)
    uni.showModal({
        title: '攝像頭授權失敗',
        content: '攝像頭授權失敗,請檢測當前瀏覽器是否有攝像頭許可權。',
        success: () => {
            uni.navigateBack({})
        }
    })
},

掃碼成功後,會自動根據地址進行跳轉到具體的二維條碼URL頁面,並帶過去一個to的引數給目標頁面。掃碼的頁面效果如下所示。

 如果我們掃碼的內容是一個URL連線,就會跳轉到具體的頁面中去,並且帶上一個to引數用於區分目標。

這樣我們在一些需要的地方,通過按鈕或者圖片來觸發一個掃碼行為即可。

 處理程式碼如下所示

uni.navigateTo({
    url: '../common/scan-qrcode'
})

如果我們的程式,需要相容App模式、小程式模式和H5等模式,那麼我們可以通過判斷來切換不同的掃碼處理,如下程式碼所示。

onScan(to) { // h5掃描二維條碼並解析  
    console.log("不支援H5掃碼 走onScan這個方法")
    let url = '../common/scan-qrcode?to=' + to;
    this.tui.href(url)
},
scanCode(to) {
    // 允許從相機和相簿掃碼
    // #ifndef H5
    uni.scanCode({
        scanType: ['qrCode', "barCode"],
        success: function(res) {
            console.log(res)

            // 微信小程式
            if (res.errMsg == "scanCode:ok") {
                // 掃描到的資訊
                // uni.$u.toast(res.result);

                var url = res.result;
                if (uni.$u.test.url(url)) {
                    console.log(url)
                    if (url.indexOf('#') > 0) {
                        let pageurl = url.split('#')[1];
                        console.log(pageurl);
                        //在頁面地址後增加一個to引數
                        uni.navigateTo({
                            url: pageurl + `&to=${to}` //加上功能
                        })
                    } else {
                        uni.$u.toast("URL格式不符");
                    }
                } else {
                    uni.$u.toast("URL格式不符");
                }

            } else {
                console.log("未識別到二維條碼,請重新嘗試!")
                uni.$u.toast('未識別到二維條碼,請重新嘗試!')
            }
        }
    });
    // #endif

    // #ifdef H5
    this.onScan(to)
    // #endif
}

這樣我們就統一處理入口了,如下呼叫程式碼所示。

packsign() {
    this.scanCode('packsign')
},

以上就是二維條碼生成和在H5中掃碼的處理操作供參考。