欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

微信小程序如何实现全局重新加载

程序员文章站 2023-11-27 21:18:16
背景: 随着业务的增加,我们服务器需要计算大量的用户数据,导致用户跟客服反应页面不能正常展示。反馈给开发后,我们一看,是服务器异常的错误。so,产品想看下我们到底有多...

背景:

随着业务的增加,我们服务器需要计算大量的用户数据,导致用户跟客服反应页面不能正常展示。反馈给开发后,我们一看,是服务器异常的错误。so,产品想看下我们到底有多少用户页面不能正常展示?

方案:

  1. 后端人员直接在阿里云后台去查哪些接口异常
  2. 前端做一个服务器报错页,这样产品在小程序后台能看到这个页面的pv,uv

技术方案

因为业务庞大,所以我们不可能区在每个页面加上重新加载的逻辑。所以初步考虑使用全局重新加载。

需要解决的问题都有哪些?

  1. 首先我们要有网络请求失败的全局控制权(要不然就需要在每个页面处理失败的情况)
  2. 需要定义好网络失败后是如何跳转到重载页(r)的(用wx.redirectto,wx.relaunch还是其他)
  3. 点击错误页的“重新加载”,如何返回或跳转到出错页(e)(用wx.redirectto,wx.relaunch还是其他)
  4. 跳转到出错页后,如何重新加载数据(把所有请求都放在page.onshow()里面?)
  5. 那如果从出错页的上个界面(p)传到出错页(e)options,那重载页(r)又将如何处理?
  6. 点击重新加载跟返回,我们希望效果效果一样,又该如何操作?

实践的方式如下

第一个问题: 比较好解决,我们基于wx.request已经封装了为fetch(如果还在用wx.request的项目可以考虑封装下,好处多多)。基于fetch我们可以用res.statuscode来判断服务器是否出错。

第二个问题: 暂且先不说具体的跳转方式是怎样的,就跳转的url这个怎么定义也需要我们来讨论下。为什么这么说,因为我们的架构涉及到了分包。分包加载意味着我们的代码不仅仅是在pages下面,还放在了package下。

基于此,我们在跳转的时候,url能直接写成'../servererror/servererror'吗?在主包下面可以正常跳转,但是在分包下,路径是'package/servererror/servererror',这样跳肯定不行。url应该是根目录下的路径,所以'/pages/servererror/servererror'。

路径确认后,我们可以跳转了。如果是wx.redirectto(关闭当前页面,跳转到应用内的某个页面),想象下关闭e跳转到r,点击重新加载,再关闭r跳转到e,这么跳转路径复杂,用户体验不好,并且options的参数需要逐级传递。wx.relaunch类似。我们用所以我们选择wx.navigateto。

第三个问题: 综合问题二的解释,跳回到e,我们用wx.navigateback。

第四个问题: 如果从r用wx.navigateback回到e的话,肯定会触发e.onshow()方法。但是有些请求我们除了写在page.onshow()里,还有些是写在page.onload()里的,所以我们必须想办法调起e.onload()。

大家对于getcurrentpages()这个方法肯定不陌生,官方定义是来获取当前页面栈,我们一般用它来获取当前页面路径。其实在这个过程中,我们是能拿到当前页面的实例的,并且实例里面有route(页面路径)options(页面传递参数)data(页面初始参数)以及各种function()等等。

利用previouspageclass()我们可以拿到e的实例,也就可以拿到e.options,当然我们也可以调e.onload()。

util.js

// 获取当前路径
function currentpagepath() {
 let pagedata = getcurrentpages()
 if (pagedata.length >= 1) {
 let len = pagedata.length - 1
 let data = pagedata[len]
 return data.route
 } else {
 return ''
 }
}

// 获取上个界面的实例
function previouspageclass() {
 let pagedata = getcurrentpages()
 if (pagedata.length >= 2) {
 let len = pagedata.length - 2
 let preclass = pagedata[len]
 return preclass
 } else {
 return ''
 }
}

module.exports = {
 currentpagepath,
 previouspageclass
}

第五个问题: 基于问题的四的方案,我们可以调e.onload(e.options)来将我们的参数回传回去。

第六个问题: 点击返回,相当于页面卸载,也就是执行了r.onunload(),这个时候我们只需要执行e.onload(e.options)这个方法,把options传过去,以及调用起e.onload()就ok了。

但是点击重新加载,我们是调的wx.navigateback(),这个方法也会走r.onunload()。这是时候可能有些苦恼了,我们隐藏掉返回按钮?发现官方并没有提供此方法。禁用r.onunload(),好像也不行。因为r.onunload()是在点击重新加载后才执行的,所以我们可以记录下用户是否点击了重新加载的行为。然后我们通过记录的行为,即便用户点击了重新加载,然后触发了r.onunload(),我们不去执行e.onload(e.options)就ok了。

// pages/servererror/servererror.js

import { previouspageclass } from '../../utils/util.js'

let isclickreload = false

page({

 onload: function (options) {
 isclickreload = false
 },
 onunload: function () {
 if(!isclickreload) {
  this.callbackparams()
 } 
 },
 /**
 * 点击事件
 */
 clickreload: function (e) {
 isclickreload = true
 wx.navigateback()
 this.callbackparams()
 },
 // 点击返回,参数回传
 callbackparams: function () {
 let preoptions = previouspageclass().options
 previouspageclass().onload(preoptions)
 }
})

至此所有问题,基本都已解决。

demo代码附上,欢迎参考。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。