如何全局重寫小程序Page函數wx對象詳解

背景

如果能夠全局改寫小程序的Page裡的生命周期方法或wx裡的函數,那麼可以做很多有意思的事情。與其說是改寫,不如說是代理裝飾。屬於是設計模式中的代理模式裝飾器模式

方案

重寫Page函數

app.js中調用:

Page = pageProxy(Page);

實現對Page裡生命周期方法裝飾。文章後面會繼續聊怎麼實現pageProxy

重寫wx對象

app.js中調用:

wx = wxProxy(wx);
復制代碼

實現對wx裡函數的裝飾。文章後面會繼續聊怎麼實現wxProxy

註意事項

上面二者都是全局生效的。

  • app.js中調用Page = pageDecorator(Page);wx = wxDecorator(wx);時,不要帶varconstlet,因為帶瞭後就隻在本頁面生效。不帶才是全局生效。
  • 必須在app.js中調用,或在app.js中引用相關的文件中執行上面2個語句。如果在頁面的js中調用,會來不及,那時候可能存在一些頁面初始化用瞭舊的Page對象。
  • 隻能執行一次,多次執行會導致多次代理/裝飾,不可取。

pageProxy

直接舉個例子,比如要修改onLoad生命周期函數的行為。

function onLoadProxy(onLoad?: WechatMiniprogram.Page.ILifetime['onLoad']): WechatMiniprogram.Page.ILifetime['onLoad'] {
  return function newOnLoad(query) {
    doSomethingWith(query); // 可訪問參數query,做一些事情,比如上報
    if (onLoad) { // 如果開發者在Page中定義瞭onLoad,我們需要調用一下開發者定義的onLoad
      return onLoad.call(this, query); // 註意這裡必須用call(this)。這裡也可以把query換成個新對象,達到修改參數的目的。(不建議直接修改query,因為會把傳入的數據給改掉,而業務開發者不知情)
    }
  };
}

function pageProxy(Page: WechatMiniprogram.Page.Constructor): WechatMiniprogram.Page.Constructor {
  return function newPage(options) {
    const newOptions = { ...options };
    newOptions.onLoad = onLoadProxy(options.onLoad);
    Page(newOptions);
  };
}

關鍵點:重寫方法時,務必使用call(this)保持this引用,否則會導致業務開發者寫onLoad的函數體時,無法訪問到符合預期的this

wxProxy

舉個例子,比如要修改wx.navigateTo導航函數的行為。

function navigateToProxy(navigateTo: WechatMiniprogram.Wx['navigateTo']): WechatMiniprogram.Wx['navigateTo'] {
  return function newNavigateTo(object) {
    doSomethingWith(object); // 可訪問參數object,做一些事情,比如上報
    // 這裡可以直接把參數換個新對象,達到修改參數的目的
    // 註意下面是淺拷貝,不建議直接修改原始options,因為會把傳入的數據給改掉,而業務開發者不知情
    return navigateTo({
      ...object,
    });
  };
}

function wxProxy(wx: WechatMiniprogram.Wx): WechatMiniprogram.Wx {
  const newWx = { ...wx };
  newWx.navigateTo = navigateToProxy(wx.navigateTo);
  return newWx;
}

總結

到此這篇關於如何全局重寫小程序Page函數wx對象的文章就介紹到這瞭,更多相關重寫小程序wx對象內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: