一、使用Taro完成掃一掃功能demo:兼容H5端、微信小程序端,適配安卓、ios。
用Taro3 React開發(fā)的demo地址: https://github.com/sweet-corns/project-taro
1、拉取項目:git clone https://github.com/sweet-corns/project-taro.git
2、當前Taro版本:
# 使用 yarn 安裝 CLI
$ yarn global add @tarojs/cli3.2.5
# 使用 cnpm 安裝 CLI
$ cnpm install -g @tarojs/cli3.2.5
# 使用 npm 安裝 CLI
$ npm install -g @tarojs/cli3.2.5
3、安裝依賴:
yarn
cnpm install
npm install
4、啟動項目:
# H5端
$ npm run dev:h5
# 微信小程序端
$ npm run dev:weapp
二、學習資料
1、Taro: 一個開放式跨端跨框架解決方案 https://taro.aotu.io/
2、weixin-js-sdk:微信公眾號開發(fā)文檔JS-SDK https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
三、微信小程序端掃一掃編寫代碼簡要概述
1、定義loading變量、防止用戶的二次點擊,掃碼成功失敗后釋放按鈕。
2、Taro.scanCode 調(diào)取微信小程序掃一掃功能。
const [loading, setLoading] = useState(true)
const onScanFun = () => {
if (loading) {
return //防止二次點擊
}
setLoading(true)
if (process.env.TARO_ENV === 'weapp') {
Taro.showLoading({
title: '加載中',
})
// 小程序掃碼
Taro.scanCode({
success: (data) => {
if (data) {
// 獲取二維碼中的參數(shù),調(diào)后臺接口
let newObj = JSON.parse(data.result)
console.log(newObj)
// 掃碼成功以后跳到簽到成功頁面、釋放加載按鈕
setLoading(false)
Taro.hideLoading()
}
},
fail: (err) => {
// 掃碼簽到失敗后跳轉(zhuǎn)到失敗頁面、釋放加載按鈕
setLoading(false)
Taro.hideLoading()
}
})
}
}
四、微信公眾號H5端掃一掃編寫代碼簡要概述
1、參考微信公眾號開發(fā)文檔、先登錄微信公眾平臺進入“公眾號設(shè)置”的“功能設(shè)置”里填寫“JS接口安全域名”。

2、配置js接口安全域名的時候,需要將文件MP_verixxxxxxx.txt(點擊下載)上傳至填寫域名或路徑指向的web服務(wù)器(或虛擬主機)的目錄。可以在taro項目中配置靜態(tài)文件打包直接拷貝。
1)一個文件夾static,將文件MP_verixxxxxxx.txt放入

2)在config/index.js中配置靜態(tài)文件拷貝

3、安裝微信JS-SDK
npm i weixin-js-sdk
4、引入weixin-js-sdk
import wx from 'weixin-js-sdk'
5、開始編寫H5版本代碼
1)定義點擊掃一掃綁定方法onScanFun,在這里區(qū)別是H5掃一掃還是微信小程序掃一掃,也要做好防止用戶二次點擊處理。
2)定義調(diào)取微信公眾號H5掃一掃方法onScanCodeWxFun()。
在這里需要兼容ios調(diào)不起來掃一掃注意:
ios調(diào)不起掃一掃:把微信JSSDk js 的資源路徑換成 https,可能是 iOS 系統(tǒng)自身安全性的原因,生產(chǎn)環(huán)境只能引用 https 開頭的路徑。
因為ios上有兼容的問題,微信公眾號調(diào)取jssdk掃一掃功能,ios第一次進入頁面調(diào)取失敗(需刷新頁面才能調(diào)取成功,Android正常)的解決方法:ios第一次進入頁面調(diào)取失敗的原因主要在于傳入的path路徑,所以ios跟安卓區(qū)別了一下 location.href.split('#')[0],解決了問題。
3)需求你公司的后臺配合,調(diào)公司溝通的接口,傳給后臺url 微信公眾號的Appid,獲取微信權(quán)限簽名。
4)獲得簽名之后傳入配置wxConfig()方法中進行,調(diào)取微信apiwx.config()
5)在微信接口調(diào)起成功的wx.ready()狀態(tài)中,調(diào)取onScanCodeWxFun()調(diào)取微信掃一掃接口wx.scanQRCode掃碼成功后,根據(jù)實際業(yè)務(wù)功能完成接下來的動作:訪問二維碼中的地址或者參數(shù)調(diào)取后臺掃碼成功接口。
6)最后的代碼復制在下方,如果有不懂的可以拉取demo進行訪問。如果遇到問題也可以私信我,樂意分享。
const [loading, setLoading] = useState(true)
//1、點擊掃一掃綁定事件
const onScanFun = () => {
if (loading) {
return //防止二次點擊
}
setLoading(true)
Taro.showLoading({
title: '加載中',
})
if (process.env.TARO_ENV === 'h5'{
//調(diào)取微信公眾號H5掃一掃定義方法
onScanCodeWxFun()
}
}
//2、調(diào)取微信公眾號H5掃一掃定義方法
const onScanCodeWx = () => {
let tokenUrl = location.href;
Taro.getSystemInfo({
success: res => {
// 1)注意ios調(diào)不起掃一掃:把微信JSSDk js 的資源路徑換成 https,可能是 iOS 系統(tǒng)自身安全性的原因,生產(chǎn)環(huán)境只能引用 https 開頭的路徑。
// 2)因為ios上有兼容的問題,微信公眾號調(diào)取jssdk掃一掃功能,ios第一次進入頁面調(diào)取失?。ㄐ杷⑿马撁娌拍苷{(diào)取成功,Android正常)的解決方法:
// 注意:ios第一次進入頁面調(diào)取失敗的原因主要在于傳入的path路徑,所以ios跟安卓區(qū)別了一下 location.href.split('#')[0],解決了問題。
if (res && res.system == "iOS") {
tokenUrl = location.href.split('#')[0]
} else {
tokenUrl = location.href;
}
let params = {
appid: '你的appid',
tokenUrl: tokenUrl
}
// 3、調(diào)后臺得接口,獲取簽名
Taro.request({
url: 'test/utl', //僅為示例,并非真實的接口地址
data: params,
header: {
'content-type': 'application/json' // 默認值
},
success: function (res) {
console.log(res.data)
if (res) {
let perData = res.data
//4、獲得簽名之后傳入配置中進行配置
wxConfig(perData.appId, perData.timestamp, perData.nonceStr, perData.signature);
}
},
fail: function (err) {
console.log(err)
Taro.hideLoading()
setLoading(false)
}
})
}
})
}
const wxConfig = (_appId, _timestamp, _nonceStr, _signature) => {
wx.config({
debug: false,// 開啟調(diào)試模式,調(diào)用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會通過log打出,僅在pc端時才會打印。
appId: _appId,// 必填,公眾號的唯一標識
timestamp: _timestamp,// 必填,生成簽名的時間戳
nonceStr: _nonceStr,// 必填,生成簽名的隨機串
signature: _signature,// 必填,簽名,見附錄1
jsApiList: ['checkJsApi', 'scanQRCode'],
// 必填,需要使用的JS接口列表,所有JS接口列表見附錄2
})
wx.ready(function () {
Taro.hideLoading()
if (process.env.TARO_ENV === 'h5') {
onScanCodeWxFun()
}
})
wx.error(function () {
// 掃碼簽到失敗后跳轉(zhuǎn)到失敗頁面、釋放掃一掃按鈕
Taro.hideLoading()
setLoading(false)
})
}
const onScanCodeWxFun = () => {
wx.scanQRCode({
needResult: 1,
scanType: ["qrCode", "barCode"],
desc: 'scanQRCode desc',
success: function (data) {
let newObj = JSON.parse(data.resultStr)
console.log(newObj)
// 調(diào)取簽到接口
Taro.hideLoading()
// 掃碼簽到失敗后跳轉(zhuǎn)到失敗頁面、釋放掃一掃按鈕
setLoading(false)
}, error: function (res) {
Taro.hideLoading()
// 掃碼簽到失敗后跳轉(zhuǎn)到失敗頁面、釋放掃一掃按鈕
setLoading(false)
}
});
}