開發背景:
.net混合開發的vue模板語法的單頁面應用,所以不存在腳手架以及沒有路由可以跳轉。
專案描述:
需要寫兩個頁面,在訂單詳情頁需要點選“請輸入手機號”進入手機號繫結頁面,手機號繫結成功後自動跳轉到訂單詳情頁,如果該手機號已經繫結成功,則不顯示“請輸入手機號”(即不可點選進入下一個頁面),只顯示該手機號。
專案思路:
在單頁面中使用v-show控制兩個頁面的切換,所以需要模擬真實兩個頁面的跳轉,即改變hash值並且監聽歷史條目變化。
一、監聽並且覆蓋微信的回退事件
當兩個頁面在同一路由下,從“手機號繫結”頁面點選微信的返回時不會進入“確認訂單”頁面,會直接返回,所以通過在url尾部新增可以識別的hash值並且使用方法進行監聽,以此判斷回到哪個頁面。
知識點儲備:
關於window.onpopstate事件其實是popstate事件在 window物件上的事件處理程式。每當處於啟用狀態的歷史記錄條目發生變化時,popstate事件就會在對應window物件上觸發.
因為給url加上了hash值雖然不會重新發出http請求但是會改變瀏覽器的訪問歷史。所以即使進入了“手機號繫結”頁面,popstate也能監聽到。
程式碼:
在“請輸入手機號”的點選事件中加上可以辨識的hash值
事件寫在methods中
複製程式碼
inputPhoneNumber() {
this.index = false;
console.log("新增hash值");
location.hash = "second";
console.log("顯示繫結手機號的hash值");
console.log(window.location);
},
複製程式碼
監聽事件寫在mouted鉤子函式中
複製程式碼
mounted() {
var url = window.location.href;
window.onpopstate = function () {
console.log("監聽回退事件");
if (location.hash.indexOf("#second") > -1) {
} else {
window.location.href = url;
}
}
}
複製程式碼
二、H5微信支付程式碼
思路:
1.在確認訂單頁面點選立即付款時,進行手機號是否繫結判斷,如果填寫手機號才可以進行下一步
2.呼叫介面向後臺傳送請求來拿去呼叫微信支付的引數(公眾號商戶付款的引數);
3.根據後臺返回的引數進行判斷,如果訂單未完成,就呼叫微信支付的內建介面,如果存在訂單,則跳轉到訂單完成頁面。
4.根據微信支付返回引數進行判斷,如果返回ok則呼叫後臺介面進行輪詢,查詢訂單是否完成。根據後臺狀態碼進行成功失敗的頁面跳轉。
程式碼:
付款按鈕:
toPayMoney() {
console.log("觸發立即付款按鈕");
var that = this;
var returnUrl = location.href;
that.disabled = true;
if (!this.phone) {
that.dialogVisible = true;
that.infoMessage = "請先輸入手機號";
console.log("確認訂單,手機號不存在時");
} else {
console.log("確認訂單,手機號存在時");
that.selectParams(); //查詢引數
console.log("確認訂單,手機號存在時,查詢支付引數");
}
},
複製程式碼
查詢支付的引數:
selectParams() {
var that = this;
var returnUrl = location.href;
$.ajax({
url: '/api/wxpay/unifiedorder',
type: "GET",
cache: false,
dataType: 'json',
data: { number: this.number },
success: function (data) {
if (data.code === 200) {
if (data.data.isValid == true) {
return location.href = "/pay/subscription/" + @Model.SubscriptionID +"/finish?tradeNo=" + @Model.Number;
} else {
var json =data.data.jsParams;
console.log("json" + (data.data.jsParams));
//調起微信支付
function onBridgeReady() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": json["appId"], //公眾號名稱,由商戶傳入
"timeStamp": json["timeStamp"], //時間戳,自1970年以來的秒數
"nonceStr": json["nonceStr"], //隨機串
"package": json["package"],
"signType": json["signType"], //微信簽名方式:
"paySign": json["paySign"] //微信簽名
},
function checkPayRes(res) {
console.log("請求後臺引數並且呼叫了微信支付");
//setInterval()
if (res.err_msg == "get_brand_wcpay_request:ok") {
that.polling();
// 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在使用者支付成功後返回 ok,但並不保證它絕對可靠。
} else {
}
}
);
}
if (typeof WeixinJSBridge === "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else {
onBridgeReady();
}
}
}
},
error: function (data) {
console.log("呼叫後臺查詢訂單未成功");
}
})
},
複製程式碼
短輪詢的函式
polling() {
var that = this;
$.ajax({
url: '/api/wxpay/unifiedorder',
type: "GET",
cache: false,
dataType: 'json',
data: { number: this.number },
success: function (data) {
if (code.data === 100) {
console.log("狀態碼101需要持續輪詢查詢");
setInterval(that.polling(), 1000);
} else if (code.data === 200) {
clearInterval(that.polling());
console.log("狀態碼200需要持續輪詢查詢");
console.log("支付成功");
location.href = "/pay/subscription/" + @Model.SubscriptionID +"/finish?tradeNo=" + @Model.Number;
} else {
console.log(data.msg);
}
}
})
}
複製程式碼
三、按鈕加鎖解鎖
其實上面的程式碼已經包括了部分加鎖與解鎖功能,下面寫一下思路:
- 使用button的 disabled屬性
- 使用v-bind給每個按鈕繫結變數。