如何全局重写小程序 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);
时,不要带var
或const
或let
,因为带了后就只在本页面生效。不带才是全局生效。 - 必须在
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;
}
写在最后
我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,联系我,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费无广告。还独立开发了《合成大西瓜重制版》。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我噢~我有空了会分享做游戏的相关技术,会在这2个专栏里分享:《教你做小游戏》、《极致用户体验》。
转载自:https://juejin.cn/post/7134728386009628703