天天看點

小程式頁面onLoad時redirectTo其它頁面,如何優雅的阻止onShow執行?

背景

有時候,我們需要在小程式的​

​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);      

繼續閱讀