背景
有時候,我們需要在小程式的
onLoad
生命周期做一些校驗,若校驗不通過,則
wx.redirectTo
其它頁面。
但是,如果直接在
onLoad
裡面執行
wx.redirectTo
,那麼小程式還是會執行完本頁面的
onShow
和
onUnload
,才會關閉本頁面。
其實大部分時候,如果你馬上要切走頁面了,
onShow
和
onUnload
沒必要執行,執行太多隻會影響你頁面切換的速度,而且一些場景下還會引入Bug。
是以,我們需要一種優雅的方式,阻止
onShow
和
onUnload
執行。
一種解決方案
在本頁面設定一個變量:
preventOnShow
,預設為false,如果需要阻止
onShow
,就設定為true。在
onShow
邏輯中,優先判斷
preventOnShow
,如果為true,就直接return。注意
preventOnShow
不要放在data裡面,因為它不需要渲染,更新它時不影響wxml。
代碼如下:
Page(
data: {},
preventOnShow: false,
onLoad(options) {
// 如果發生特殊情況,就直接redirectTo其它頁面
if (...) {
this.preventOnShow = true;
wx.redirectTo({ url: '...' });
return;
}
// ... 其它onLoad邏輯
},
onShow() {
if (this.preventOnShow) return;
// ... 其它onShow邏輯
更優雅的解決方案
為什麼需要更優雅的解決方案?
因為上面的解決方案還不夠好。我們需要在每個頁面都加這樣的重複邏輯:
Page(
preventOnShow: false,
onShow() {
if (this.preventOnShow) return;
// ... 其它onShow邏輯
一旦某個頁面忘記加,那麼
preventOnShow
就失效了。
是以,我們最好通過某種方式一次性全局加上這種邏輯,避免開發者建立某頁面時忘記,減少了出錯率。這展現了工程化的思想。
具體怎麼做?參考文章:《如何全局重寫小程式 Page函數 wx對象?》。
function onShowProxy(onShow) {
return function newOnShow() {
if (this.preventOnShow) return;
if (onShow) {
return onShow.call(this);
}
};
}
function pageProxy(Page: WechatMiniprogram.Page.Constructor): WechatMiniprogram.Page.Constructor {
return function newPage(options) {
Page({
...options,
preventOnShow: false,
onShow: onShowProxy(options.onShow),
});
};
}
Page = pageProxy(Page);