你有经历过在<span style="font-size: 16px;">小程序里进行页面跳转时页面被重复打开的情况吗?</span>
如果有的话您可以继续往下看。
随着我们业务的拓展,功能的增加小程序包体变大,我们不得不使用小程序分包来解决首屏加载问题。
在解决问题的时候,必将会引起另一些问题,比如:
小程序启动之后,用户通过按钮打开未访问过的分包路由页面,跳转时由于分包加载数据会耗时,界面上的元素仍然可以响应用户的操作,如果用户不小心或由于焦急重复点击按钮后,按钮的事件处理函数就会随着点击重复执行,页面会被重复打开好几次。
但一旦页面被加载过,跳转是非常快的,就很难出现重复点击的情况。
例如在下面路由配置中
{
"subPackages": [
{
"root": "pages/index/",
"pages": [
"index"
]
},
{
"root": "pages/post/",
"pages": [
"details",
"list",
]
}
]
}
我们给首页的Page里添加一个点击事件来跳转到我们的文章页面
handleArticleTap(e){
const pid = e.currentTarget.dataset.pid;
consturl =`pages/post/details?pid=${pid};
wx.navigateTo({url});
}
我们打开页面 pages/index/index 来访问小程序的首页,首页上存在一些推荐文章的链接按钮,用户可通过这些按钮来查看我们的文章。
在实际情况中,我们偶尔会观察到诡异的现象:我们的文章页面被重复打开了。
用户首次通过点击跳转按钮来跳转到pages/post/details?pid=1 时,pages/post/details 页面未被小程序框架加载,页面会处于假死状态,在Android上可以明显的看到系统显示【模块加载中】 这样的提示。
重复打开页面会给用户带来不必要的麻烦。
解决这个问题,那就是上锁
wx.navigateTo 给我们提供了一个success接口,我们的处理函数可以稍作修改就解决这个问题?
handleArticleTap(e){
if (this.handleArticleTapLock){
return;
}
this.handleArticleTapLock=true;
const pid = e.currentTarget.dataset.pid;
const url =`pages/post/details?pid=${pid};
wx.navigateTo({
url,
success()=>{
this.handleArticleTapLock=false;
}
});
}
文档上并没有描述success的触发时机,然后我就亲手试了一下,发现果然不行哦。
页面还没被打开navigateTo__就success了!!__
那我们就试试通过Page的onShow生命周期上锁:
onShow(){
this.handleArticleTapLock=false;
},
handleArticleTap(e){
if (this.handleArticleTapLock){
return;
}
this.handleArticleTapLock=true;
const pid = e.currentTarget.dataset.pid;
const url =`pages/post/details?pid=${pid}`;
wx.navigateTo({
url
});
}
这下只能点一下了,除非页面退回来,点再多下都不管用。