知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們在追求其視覺表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏壧峁┍憬莸闹С郑?
您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
微信小程序之頁面攔截器
發(fā)表時(shí)間:2021-4-30
發(fā)布人:葵宇科技
瀏覽次數(shù):358
場景
- 小程序有52個(gè)頁面,其中13個(gè)頁面無需任何身份,另外39個(gè)頁面需要系統(tǒng)角色。對于這39個(gè)頁面,如果微信用戶沒有系統(tǒng)角色,則跳轉(zhuǎn)到登錄頁。
- 是否有系統(tǒng)角色信息需要通過異步請求來獲取。
需求分析&實(shí)現(xiàn)
對需求進(jìn)行抽象,其實(shí)要的就是一個(gè)過濾器,對小程序頁面的訪問進(jìn)行過濾,符合條件的通過,不符合條件進(jìn)行其他處理。
使用過php的laravel框架的童鞋,肯定一下子就聯(lián)想到了laravel框架的http中間件:HTTP 中間件提供一個(gè)方便的機(jī)制來過濾進(jìn)入應(yīng)用程序的 HTTP 請求,例如,Laravel 默認(rèn)包含了一個(gè)中間件來檢驗(yàn)用戶身份驗(yàn)證,如果用戶沒有經(jīng)過身份驗(yàn)證,中間件會(huì)將用戶導(dǎo)向登錄頁面,然而,如果用戶通過身份驗(yàn)證,中間件將會(huì)允許這個(gè)請求進(jìn)一步繼續(xù)前進(jìn)。當(dāng)然,除了身份驗(yàn)證之外,中間件也可以被用來執(zhí)行各式各樣的任務(wù),CORS 中間件負(fù)責(zé)替所有即將離開程序的響應(yīng)加入適當(dāng)?shù)捻憫?yīng)頭,一個(gè)日志中間件可以記錄所有傳入應(yīng)用程序的請求。
令人憂桑的是,微信小程序并沒有提供針對Page實(shí)例的中間件機(jī)制。所以只能從Page實(shí)例的生命周期處下手。
對于onLoad,一個(gè)頁面只會(huì)調(diào)用一次;對于onShow,每次打開頁面(比如小程序從后臺(tái)轉(zhuǎn)到前臺(tái))都會(huì)調(diào)用一次。
在onLoad或者onShow鉤子函數(shù)里,對用戶身份進(jìn)行校驗(yàn),通過后則拉取該頁面需要的數(shù)據(jù),否則跳轉(zhuǎn)到登錄頁。
//orderDetail.js
onShow: function () {
let that = this;
//身份校驗(yàn)
service.identityCheck(() => {
//跳轉(zhuǎn)到登錄頁
wx.redirectTo({
url: "/pages/common/login/login"
});
}, () => {
//獲取頁面數(shù)據(jù)等等
that.getDetail(this.orderId);
...
}
);
},
不過,每個(gè)頁面都要這樣寫,重復(fù)代碼好多啊,侵入性也強(qiáng)。不如用裝飾函數(shù)(高大上的說法是裝飾者模式)來包裝一下:
//filter.js
function identityFilter(pageObj){
if(pageObj.onShow){
let _onShow = pageObj.onShow;
pageObj.onShow = function(){
service.identityCheck(()=>{
//跳轉(zhuǎn)到登錄頁
wx.redirectTo({
url: "/pages/common/login/login"
});
},()=>{
//獲取頁面實(shí)例,防止this劫持
let currentInstance = getPageInstance();
_onShow.call(currentInstance);
});
}
}
return pageObj;
}
function getPageInstance(){
var pages = getCurrentPages();
return pages[pages.length - 1];
}
exports.identityFilter = identityFilter;
filter.js
用以提供過濾器方法,除了現(xiàn)有的用戶身份攔截,后續(xù)如果需要其他攔截,可以在這個(gè)文件增加。然后,在需要用戶身份攔截的小程序頁面代碼里,用filter.identityFilter
處理一下就可以了:
//orderDetail.js
let filter = require('filter.js');
Page(filter.identityFilter({
...
onShow: function () {
//獲取頁面數(shù)據(jù)等等
this.getDetail(this.orderId);
//...
},
...
}));
使用Promise進(jìn)行優(yōu)化
上面的實(shí)現(xiàn)中,每次訪問頁面,都會(huì)執(zhí)行一次獲取用戶身份的方法(就是上面代碼里的service. identityCheck
)。其實(shí)沒有必要,在小程序啟動(dòng)的時(shí)候獲取一次就行了。也就是說,放在app.js的onLaunch方法里執(zhí)行。
每個(gè)小程序頁面實(shí)例化時(shí),一般也會(huì)執(zhí)行異步方法,用來獲取頁面需要的數(shù)據(jù)。關(guān)鍵在于,我們需要保證,頁面的異步方法 必須在 獲取用戶身份的異步請求 之后執(zhí)行。
毋容置疑,Promise最擅長處理異步請求的執(zhí)行順序了。主子,快放代碼粗來:
//app.js
App({
onLaunch:function(){
let p = new Promise(function(resolve,reject){
service.identityCheck(resolve,reject);
});
this.globalData.promise = p;
},
...
globalData: {
promise:null,
}
});
//filter.js
const appData = https://www.wxapp-union.com/getApp().globalData;
function identityFilter(pageObj){
if(pageObj.onShow){
let _onShow = pageObj.onShow;
pageObj.onShow = function(){
//改動(dòng)點(diǎn)
appData.promise.then(()=>{
//跳轉(zhuǎn)到登錄頁
wx.redirectTo({
url: "/pages/common/login/login"
});
},()=>{
//獲取頁面實(shí)例,防止this劫持
let currentInstance = getPageInstance();
_onShow.call(currentInstance);
});
}
}
return pageObj;
}
小結(jié)
基本實(shí)現(xiàn)了小程序頁面的用戶身份攔截器,但是比起laravel的http中間件還是遜色一些:
- 需要對每個(gè)頁面代碼包裝一層。
- 即使用戶身份校驗(yàn)不通過,小程序也并不會(huì)阻塞頁面的渲染。假如獲取用戶身份的異步方法一分鐘才執(zhí)行完,小程序頁面還是會(huì)展示出來,一分鐘之后才跳轉(zhuǎn)到登錄頁。需要自己增加邏輯,比如在這一分鐘內(nèi),頁面展示空白內(nèi)容。
嗯,對小程序的新特性保持關(guān)注,后面看看怎么改進(jìn)~
相關(guān)案例查看更多
相關(guān)閱讀
- 人口普查小程序
- 網(wǎng)站建設(shè)報(bào)價(jià)
- 云南網(wǎng)絡(luò)公司
- 汽車報(bào)廢拆解管理系統(tǒng)
- 軟件定制
- 報(bào)廢車管理系統(tǒng)
- web開發(fā)
- 網(wǎng)站建設(shè)公司哪家好
- 云南網(wǎng)站建設(shè)特性
- 英文網(wǎng)站建設(shè)公司
- 昆明網(wǎng)站設(shè)計(jì)
- 云南花農(nóng)小程序
- 花農(nóng)小程序
- 云南微信小程序開發(fā)
- 曲靖小程序開發(fā)
- 網(wǎng)站優(yōu)化
- 網(wǎng)站建設(shè)哪家強(qiáng)
- 網(wǎng)站建設(shè)制作
- 網(wǎng)站搭建
- 云南小程序開發(fā)公司
- 二叉樹
- painter
- 網(wǎng)站開發(fā)公司哪家好
- 公眾號(hào)模板消息
- 網(wǎng)站建設(shè)公司地址
- 云南小程序設(shè)計(jì)
- 小程序定制
- php網(wǎng)站
- 云南網(wǎng)站建設(shè)哪家強(qiáng)
- 云南網(wǎng)站建設(shè)公司地址