背景
有时候,我们需要在小程序的
onLoad
生命周期做一些校验,若校验不通过,则
wx.redirectTo
其它页面。
但是,如果直接在
onLoad
里面执行
wx.redirectTo
,那么小程序还是会执行完本页面的
onShow
和
onUnload
,才会关闭本页面。
其实大部分时候,如果你马上要切走页面了,
onShow
和
onUnload
没必要执行,执行太多只会影响你页面切换的速度,而且一些场景下还会引入Bug。
所以,我们需要一种优雅的方式,阻止
onShow
和
onUnload
执行。
一种解决方案
在本页面设置一个变量:
preventOnShow
,默认为false,如果需要阻止
onShow
,就设置为true。在
onShow
逻辑中,优先判断
preventOnShow
,如果为true,就直接return。注意
preventOnShow
不要放在data里面,因为它不需要渲染,更新它时不影响wxml。
代码如下:
Page(
data: {},
preventOnShow: false,
onLoad(options) {
// 如果发生特殊情况,就直接redirectTo其它页面
if (...) {
this.preventOnShow = true;
wx.redirectTo({ url: '...' });
return;
}
// ... 其它onLoad逻辑
},
onShow() {
if (this.preventOnShow) return;
// ... 其它onShow逻辑
更优雅的解决方案
为什么需要更优雅的解决方案?
因为上面的解决方案还不够好。我们需要在每个页面都加这样的重复逻辑:
Page(
preventOnShow: false,
onShow() {
if (this.preventOnShow) return;
// ... 其它onShow逻辑
一旦某个页面忘记加,那么
preventOnShow
就失效了。
因此,我们最好通过某种方式一次性全局加上这种逻辑,避免开发者新建某页面时忘记,减少了出错率。这体现了工程化的思想。
具体怎么做?参考文章:《如何全局重写小程序 Page函数 wx对象?》。
function onShowProxy(onShow) {
return function newOnShow() {
if (this.preventOnShow) return;
if (onShow) {
return onShow.call(this);
}
};
}
function pageProxy(Page: WechatMiniprogram.Page.Constructor): WechatMiniprogram.Page.Constructor {
return function newPage(options) {
Page({
...options,
preventOnShow: false,
onShow: onShowProxy(options.onShow),
});
};
}
Page = pageProxy(Page);