本文是了解微信小程序 Taro 的自动埋点。
|
在做各种各样的业务时,我们不可避免的需要在业务中进行埋点,这些埋点通常包含但不限于曝光、点击、停留时长、离开页面等场景,而在小程序中因为其和浏览器不同的架构,导致了监听页面变的更加困难,通常我们都会通过重写 现状在多端统一的 基本的重写在微信小程序中,其暴露的 const _originalComponent = Component;const wrappedComponent = function (options) {
...do something before real Component return _originalComponent(options);
}复制代码这样可以很快的解决问题,但是当我们在另一个小程序做这件事情的时候,我们就又需要手动做一次这些处理,难免有些麻烦,为什么不找一个更通用的方案,我们只用关注我们需要关注的业务(埋点)就行了呢? 解决方案
根问题在解决问题之前,不如让我们先看看这个问题的本质是什么。想在小程序中进行自动的埋点,其实要做的就是在小程序指定的生命周期里做一些固定的处理,所以我们自动埋点的问题实际上是如何劫持小程序的生命周期,而要劫持小程序的生命周期,我们需要做的就是去重写 如何解决在解决这个问题之前,我们要把自己需要解决的问题拆分出来:
我们在上面的基础解决办法对如何重写 step 1首先我们在重写 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;
};复制代码经过如上两步,我们就能对指定的生命周期进行劫持并注入我们自己的 weapp-lifecycle-hook-plugin为了方便直接对微信小程序原生环境和 安装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 的自动埋点的详细内容,更多请关注模板之家(www.mb5.com.cn)其它相关文章! |
