中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

微信小程序Taro的自動埋點是什么

發布時間:2021-03-10 15:15:23 來源:億速云 閱讀:221 作者:小新 欄目:移動開發

這篇文章主要介紹了微信小程序Taro的自動埋點是什么,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

現狀

在多端統一的Taro中,我們不再能看到顯式的 Page 調用,甚至 Taro 打包之后的代碼里也不再存在任何 Page 的跡象,取而代之的則是小程序原生的 Component(這一點大家通過觀察打包后的內容可以得知),所以為了實現微信小程序在Taro中的自動埋點,我們需要換一個策略:重寫Component

基本的重寫

在微信小程序中,其暴露的ComponentPage 能夠直接被重寫并進行賦值:

const _originalComponent = Component;const wrappedComponent = function (options) {
    ...do something before real Component    return _originalComponent(options);
}復制代碼

這樣可以很快的解決問題,但是當我們在另一個小程序做這件事情的時候,我們就又需要手動做一次這些處理,難免有些麻煩,為什么不找一個更通用的方案,我們只用關注我們需要關注的業務(埋點)就行了呢?

解決方案

重中之重,從零開始思考,掌握真正問題,接近問題本質

根問題

在解決問題之前,不如讓我們先看看這個問題的本質是什么。想在小程序中進行自動的埋點,其實要做的就是在小程序指定的生命周期里做一些固定的處理,所以我們自動埋點的問題實際上是如何劫持小程序的生命周期,而要劫持小程序的生命周期,我們需要做的就是去重寫options

如何解決

在解決這個問題之前,我們要把自己需要解決的問題拆分出來:

  • 應該怎么重寫 options

  • 應該重寫哪些 options

  • 怎樣把自己的業務注入到監聽的生命周期中。

我們在上面的基礎解決辦法對如何重寫options就已經有了答案,我們只需要在原小程序提供的方法外再包裹一層即可解決,同時為了保證我們的解決方案能適用于原生小程序和Taro這種多端統一的小程序方案,我們應該同時支持重寫ComponentPage,而對于最后一個問題,我們可以思考一下js中的事件系統,相似的我們也可以實現一套發布訂閱的邏輯,只需要定制觸發事件(生命周期)和listeners,再針對生命周期原有邏輯進行包裝即可;

step 1

首先我們在重寫ComponentPage之前應當保存原始的方法,避免原始方法被污染我們無法回退,這之后再去將小程序中的所有生命周期進行枚舉生成一個默認的事件對象中,保證我們在注冊了對應生命周期的listeners后能通過尋址找到并對原生命周期方法進行重寫。

export const ProxyLifecycle = {
  ON_READY: 'onReady',
  ON_SHOW: 'onShow',
  ON_HIDE: 'onHide',
  ON_LOAD: 'onLoad',
  ON_UNLOAD: 'onUnload',
  CREATED: 'created',
  ATTACHED: 'attached',
  READY: 'ready',
  MOVED: 'moved',
  DETACHED: 'detached',
  SHOW: 'show',
  HIDE: 'hide',
  RESIZE: 'resize',
};public constructor() {  this.initLifecycleHooks();  this.wechatOriginalPage = getWxPage();  this.wechatOriginalComponent = getWxComponent();
}// 初始化所有生命周期的鉤子函數private initLifecycleHooks(): void {  this.lifecycleHooks = Object.keys(ProxyLifecycle).reduce((res, cur: keyof typeof ProxyLifecycle) => {
    res[ProxyLifecycle[cur]] = [] as WeappLifecycleHook[];    return res;
  }, {} as Record<string, WeappLifecycleHook[]>);
}復制代碼
step 2

在這一步我們只需要將監聽函數放到我們第一步中聲明的事件對象中,然后執行重寫流程即可:

public addLifecycleListener(lifeTimeOrLifecycle: string, listener: WeappLifecycleHook): OverrideWechatPage {  // 針對指定周期定義Hooks
  this.lifecycleHooks[lifeTimeOrLifecycle].push(listener);  const _Page = this.wechatOriginalPage;  const _Component = this.wechatOriginalComponent;  const self = this;  const wrapMode = this.checkMode(lifeTimeOrLifecycle);  const componentNeedWrap = ['component', 'pageLifetimes'].includes(wrapMode);  const wrapper = function wrapFunc(options: IOverrideWechatPageInitOptions): string | void {    const optionsKey = wrapMode === 'pageLifetimes' ? 'pageLifetimes' : '';
    options = self.findHooksAndWrap(lifeTimeOrLifecycle, optionsKey, options);    const res = componentNeedWrap ? _Component(options) : _Page(options);

    options.__router__ = (wrapper as any).__route__ = res;    return res;
  };

  (wrapper as any).__route__ = '';  if (componentNeedWrap) {
    overrideWxComponent(wrapper);
  } else {
    overrideWxPage(wrapper);
  }  return this;
}/**
 * 為對應的生命周期重寫options
 * @param proxyLifecycleOrTime 需要攔截的生命周期
 * @param optionsKey 需要重寫的 optionsKey,此處用于 lifetime 模式
 * @param options 需要被重寫的 options
 * @returns {IOverrideWechatPageInitOptions} 被重寫的options
 */private findHooksAndWrap = (
  proxyLifecycleOrTime: string,
  optionsKey = '',
  options: IOverrideWechatPageInitOptions,
): IOverrideWechatPageInitOptions => {  let processedOptions = { ...options };  const hooks = this.lifecycleHooks[proxyLifecycleOrTime];
  processedOptions = OverrideWechatPage.wrapLifecycleOptions(proxyLifecycleOrTime, hooks, optionsKey, options);  return processedOptions;
};/**
 * 重寫options
 * @param lifecycle 需要被重寫的生命周期
 * @param hooks 為生命周期添加的鉤子函數
 * @param optionsKey 需要被重寫的optionsKey,僅用于 lifetime 模式
 * @param options 需要被重寫的配置項
 * @returns {IOverrideWechatPageInitOptions} 被重寫的options
 */private static wrapLifecycleOptions = (
  lifecycle: string,
  hooks: WeappLifecycleHook[],
  optionsKey = '',
  options: IOverrideWechatPageInitOptions,
): IOverrideWechatPageInitOptions => {  let currentOptions = { ...options };  const originalMethod = optionsKey ? (currentOptions[optionsKey] || {})[lifecycle] : currentOptions[lifecycle];  const runLifecycleHooks = (): void => {
    hooks.forEach((hook) => {      if (currentOptions.__isPage__) {
        hook(currentOptions);
      }
    });
  };  const warpMethod = runFunctionWithAop([runLifecycleHooks], originalMethod);

  currentOptions = optionsKey
    ? {
        ...currentOptions,
        [optionsKey]: {
          ...options[optionsKey],
          ...(currentOptions[optionsKey] || {}),
          [lifecycle]: warpMethod,
        },
      }
    : {
        ...currentOptions,
        [lifecycle]: warpMethod,
      };  return currentOptions;
};復制代碼

經過如上兩步,我們就能對指定的生命周期進行劫持并注入我們自己的listeners,使用被重寫過Component或者Page就會自動觸發這些 listeners

weapp-lifecycle-hook-plugin

為了方便直接對微信小程序原生環境和Taro等多端統一方案進行這一套通用的解決方案,我實現了一個插件來解決這個問題(私心安利)

安裝
npm install weapp-lifecycle-hook-plugin
或者
yarn add weapp-lifecycle-hook-plugin復制代碼
使用
import OverrideWechatPage, { setupLifecycleListeners, ProxyLifecycle } from 'weapp-lifecycle-hook-plugin';

// 供 setupLifecycleListeners 使用的 hook 函數,接受一個參數,為當前組件/頁面的options
function simpleReportGoPage(options: any): void {
  console.log('goPage', options);
}

// setupListeners
class App extends Component {
  constructor(props) {
    super(props);
  }

  componentWillMount() {
    // ...
    // 手動創建的實例和使用 setupLifecycleListeners 創建的實例不是同一個,所以需要銷毀時需要單獨對其進行銷毀
    // 直接調用實例方式
    const instance = new OverrideWechatPage(this.config.pages);
    // 直接調用實例上的 addListener 方法在全局增加監聽函數,可鏈式調用
    instance.addLifecycleListener(ProxyLifecycle.SHOW, simpleReportGoPage);
    // setupListeners 的使用
    setupLifecycleListeners(ProxyLifecycle.SHOW, [simpleReportGoPage], this.config.pages);
    // ...
  }

  // ...
}復制代碼

感謝你能夠認真閱讀完這篇文章,希望小編分享的“微信小程序Taro的自動埋點是什么”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大丰市| 宁晋县| 合肥市| 水富县| 施秉县| 浑源县| 阜新| 许昌市| 井研县| 沂南县| 天气| 夏邑县| 河间市| 鹤峰县| 高台县| 光山县| 鲁甸县| 珲春市| 延津县| 定结县| 收藏| 永清县| 鹤岗市| 临清市| 延安市| 察隅县| 沙雅县| 楚雄市| 雅江县| 沂南县| 万年县| 永泰县| 青浦区| 深州市| 广安市| 济南市| 礼泉县| 南昌县| 建湖县| 凤山市| 扶沟县|