在UniApp的H5項目中,生成二維碼和掃描二維碼的操作處理

在我們基於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)

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

不過該介面卻不能在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中掃碼的處理操作供參考。