需求背景
以用户的维度来采集页面的UV,PV,等数据做统计
实现
思路就是对hook监听了,hook每触发一次,就to do something,目前微信小程序存在hook的,就是APP,Page,Component。总不能在每个存在生命周期的地方去加一段to do something的代码,其一影响业务,其二维护和开发难度过高。
那么我们考虑以依赖的方式注入,可以尝试在app.js输出App。Page和Component同理
console.log(App)
相关hook文档
从以上说明构造出以下的代码
// collect.js
(() => {
let _App = App;
let _Page = Page;
let _Component = Component;
// 需监听的生命周期
let appDefaultHookList = ['onLaunch', 'onShow', 'onHide', 'onError', 'onPageNotFound'];
let pageDefaultHookList = ['onLoad', 'onShow', 'onReady', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage'];
const collect = {
}
})()
怎么注入?
/*举个例子*/
// 改写
console.log(1); // 1
window.console.log = text => `${text}, add...`;
console.log(1); // "1, add..."
// 改写后追加
let _Number = Number;
Number = function(args){ console.log(args); return _Number.call(this, args) }
Number('1')
//这个时候会输出"1, add..."和返回Int 1
从以上原理得出以下代码
// collect.js
(() => {
let _App = App;
let _Page = Page;
let _Component = Component;
// 需监听的生命周期
let appDefaultHookList = ['onLaunch', 'onShow', 'onHide', 'onError', 'onPageNotFound'];
let pageDefaultHookList = ['onLoad', 'onShow', 'onReady', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage'];
const collect = {
hookTriggerHandle(instance, hook, scene){
// 有些hook可能没有被注册所以得判断一下是否存在
if(instance.hasOwnProperty(hook)){
let pristine = instance[hook];
instance[hook] = function(args){
collect.sendRubbish.call(this, args, hook, scene);
return pristine.call(this, args);
}
}else if(scene == 'PAGE'){
if(hook == pageDefaultHookList[1] || hook == pageDefaultHookList[3] || hook == pageDefaultHookList[4]){
instance[hook] = function(args){
collect.sendRubbish.call(this, args, hook, scene);
}
}
}
}
},
}
// injection
App = (me) => {
appDefaultHookList.map(hookName => collect.hookTriggerHandle(me, hookName, 'APP'));
_App(me);
}
Page = (me) => {
pageDefaultHookList.map(hookName => collect.hookTriggerHandle(me, hookName, 'PAGE'));
_Page(me);
}
Component = (me) => {
//do something...
_Component(me);
}
})()
发送数据给服务端
// collect.js
(() => {
let _App = App;
let _Page = Page;
let _Component = Component;
// 需监听的生命周期
let appDefaultHookList = ['onLaunch', 'onShow', 'onHide', 'onError', 'onPageNotFound'];
let pageDefaultHookList = ['onLoad', 'onShow', 'onReady', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage'];
const collect = {
hookTriggerHandle(instance, hook, scene){
// 有些hook可能没有被注册所以得判断一下是否存在
if(instance.hasOwnProperty(hook)){
let pristine = instance[hook];
instance[hook] = function(args){
collect.sendRubbish.call(this, args, hook, scene);
return pristine.call(this, args);
}
}else if(scene == 'PAGE'){
if(hook == pageDefaultHookList[1] || hook == pageDefaultHookList[3] || hook == pageDefaultHookList[4]){
instance[hook] = function(args){
collect.sendRubbish.call(this, args, hook, scene);
}
}
}
}
},
sendRubbish(data, hook, scene){
if(scene == 'APP'){
// onLaunch
if(hook == appDefaultHookList[0]){
// 场景值
collect.data.scene = data.scene;
collect.collectGarbage.call(this, {
args: null,
event: hook,
stayTime: null,
createUnix: +new Date(),
other: data.query,
isFirstOpen: true
});
}
}else if(scene == 'PAGE'){
// special handle
if(hook == pageDefaultHookList[1]){
// onShow
if(this.__route__ != collect.data.prevPageInfo.url){
// mark
collect.data.prevPageInfo = {
args: data || null,
event: hook,
stayTime: null,
createUnix: +new Date(),
other: this.options || null
}
}
}
}
/*
push 发送给服务端
collectGarbage 函数就不细写出来了,就是wx.request
*/
collect.collectGarbage.call(this, {
args: data || null,
event: hook,
stayTime: 0,
createUnix: +new Date(),
other: this.options || null
});
}
}
// injection
App = (me) => {
appDefaultHookList.map(hookName => collect.hookTriggerHandle(me, hookName, 'APP'));
_App(me);
}
Page = (me) => {
pageDefaultHookList.map(hookName => collect.hookTriggerHandle(me, hookName, 'PAGE'));
_Page(me);
}
Component = (me) => {
//do something...
_Component(me);
}
})()
总结
最后在app.js 引入 collect.js 即可实现效果,其实很可以做很多扩展,比如某个页面的函数执行触发之类的,如果哪里不对的,欢迎指出交流
本文由 coderl 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Jul 10, 2019 at 10:54 am