最近完成了一個租車類型的小程序,無意間測試到了一個bug,從而發(fā)現(xiàn)了微信支付與onShow之間的聯(lián)系,想記錄下來,分享給更多的小伙伴。
一、生命周期回調(diào)函數(shù)
1.onLoad
頁面加載時觸發(fā)。一個頁面只會調(diào)用一次,即第一次進(jìn)入該頁面時才會觸發(fā),在onShow之前觸發(fā),若頁面獲取顯示數(shù)據(jù)固定(如簽到數(shù)據(jù)等),可在onShow中進(jìn)行數(shù)據(jù)交互,可以在 onLoad 的參數(shù)中獲取打開當(dāng)前頁面路徑中的參數(shù)或二維碼信息的參數(shù),可用于路徑間傳參或二維碼信息的獲取等。
onLoad(options) {}
2.onShow
頁面顯示/切入前臺時觸發(fā)。一般是進(jìn)入頁面時觸發(fā),在onLoad之后觸發(fā),若頁面的獲取顯示數(shù)據(jù)不固定,經(jīng)常變化(如:商品列表、車輛列表等),可在onShow中進(jìn)行數(shù)據(jù)交互,獲取數(shù)據(jù)信息。
onShow() {}
3.onReady
頁面初次渲染完成時觸發(fā)。一個頁面只會調(diào)用一次,代表頁面已經(jīng)準(zhǔn)備妥當(dāng),可以和視圖層進(jìn)行交互。注意:對界面內(nèi)容進(jìn)行設(shè)置的 API 如wx.setNavigationBarTitle,請在onReady之后進(jìn)行,此時的DOM都已經(jīng)渲染完成。
onReady() {}
4.onHide
頁面隱藏/切入后臺時觸發(fā)。 如 navigateTo 或底部 tab 切換到其他頁面,小程序切入后臺等,與onShow對應(yīng)。若頁面中有setInterval、setTimeout定時器,可用于定時器的清除或者進(jìn)行清除數(shù)據(jù)的操作等。
onHide()
5.onUnload
頁面卸載時觸發(fā)。如redirectTo或navigateBack到其他頁面時,關(guān)閉當(dāng)前頁面,與onLoad對應(yīng),也可進(jìn)行定時器和數(shù)據(jù)的清除等。
onUnload()
二、微信支付
發(fā)起微信支付 wx.requestPayment(Object object)
//調(diào)起微信支付,res.data.data.ChooseWXPayInfo為后臺返回的數(shù)據(jù)
let chooseWXPayInfo = res.data.data.ChooseWXPayInfo;
//必傳的4個參數(shù):timeStamp,nonceStr,package,paySign
wx.requestPayment({
'nonceStr': chooseWXPayInfo.nonceStr,
'package': chooseWXPayInfo.packageInfo,
'signType': chooseWXPayInfo.signType,
'timeStamp': chooseWXPayInfo.timeStamp,
'paySign': chooseWXPayInfo.paySign,
// 支付成功
'success': function(res) {
that.data.isPay = true;
wx.showToast({
title: '支付成功',
image: '/image/icon_success.png',
duration: 1500,
mask: true
})
// 支付成功后跳轉(zhuǎn)頁面
setTimeout(function() {
wx.redirectTo({
url: `../takeCar/takeCar`
});
}, 2000);
},
// 支付失敗
'fail': function(res) {
that.data.isPay = false;
wx.showToast({
title: '支付失敗',
image: '/image/icon_fail.png',
duration: 2000,
mask: true
})
}
})
這里介紹一下我的頁面邏輯:
在rentCar(項目中的一個文件)中,要列出掃碼進(jìn)來的車輛列表,這個數(shù)據(jù)可變性比較大,所以把數(shù)據(jù)交互放在onShow()中,寫了一個方法:
onShow: function() {
this.getDevice();
},
getDevice(){
let that = this;
wxRequest('device/map/getScanInfo', nowData, "POST").then((res) => {
if (res.data.code == 200) {
let nowboxList = res.data.data.boxList;
// 這里判斷返回車輛的長度
if (nowboxList.length > 0) {
that.setData({
boxList: nowboxList
})
}else{
wx.showModal({
title: '溫馨提示',
content: '暫無可租車輛,請前往其他機柜',
showCancel: false,
confirmColor: '#fe861b',
success(res) {
if (res.confirm) {
wx.reLaunch({
url: '/pages/map/map'
})
}
}
})
}
} else if (res.data.code == -3) {
// 這里判斷沒有可用的車輛
wx.showModal({
title: '溫馨提示',
content: res.data.msg,
showCancel: false,
confirmColor: '#fe861b',
success(res) {
if (res.confirm) {
wx.reLaunch({
url: '/pages/map/map'
})
}
}
})
return;
} else {
wx.showToast({
title: res.data.msg,
icon: 'none',
duration: 2000,
mask: true
})
}
}).catch((errMsg) => {
});
},
以上就是相關(guān)代碼,編譯器里面按照既定的邏輯走流程,沒什么問題??墒钱?dāng)用手機體驗,調(diào)用微信支付后,先執(zhí)行app onHide回調(diào),再執(zhí)行支付回調(diào),然后執(zhí)行app onShow回調(diào),即支付之前會調(diào)用onHide(),支付之后,不管是支付成功或是失敗,會調(diào)用onShow(),從而調(diào)用onShow里面的方法,由于之前不知道有這種關(guān)聯(lián),所以代碼邏輯存在問題。
既然微信有這樣的機制,那就要想辦法解決問題了,這里我用了變量isPay,來進(jìn)行判斷要不要調(diào)用getDevice方法
//規(guī)定isPay為false表示支付成功,isPay為true表示支付失敗,isPay初始化為false
data: {
isPay:false
},
onShow: function() {
//如果isPay為false,則調(diào)用getDevice方法
if (!this.data.isPay) {
this.getDevice();
}
},
以上,用一個變量來判斷,就完美解決問題啦,真好O(∩_∩)O~
