VIP用户交流群:462197261 收藏本站北冥有鱼 互联网前沿资源第一站 助力全行业互联网+
在线客服:78895949
tonglan
  • 当前位置:
  • 微信小程序如何实现全局重新加载

    背景:

    随着业务的增加,我们服务器需要计算大量的用户数据,导致用户跟客服反应页面不能正常展示。反馈给开发后,我们一看,是服务器异常的错误。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代码附上,欢迎参考。

    总结

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

    您可能感兴趣的文章:

    • 微信小程序全局变量改变监听的实现方法
    • 微信小程序设置全局请求URL及封装wx.request请求操作示例
    • 微信小程序全局变量功能与用法详解
    • 微信小程序实现全局搜索代码高亮的示例
    • 微信小程序本作用域下调用全局JS详解及实例
    • 微信小程序 定义全局数据、函数复用、模版等详细介绍
    • 微信小程序全局变量的设置、使用、修改过程解析

    广而告之:
    热门推荐:
    微信小程序开发教程之增加mixin扩展

    Mixin简介 Mixin(织入)模式并不是GOF的《设计模式》归纳中的一种,但是在各种语言以及框架都会发现该模式(或者思想)的一些应用。简单来说,Mixin是带有全部实现或者部分实现的接口,其主要作用是更好的代码复用。 Mixin这个概念在React, Vue中都有支持,它为我们抽象业务逻···

    PHP中的访问修饰符简单比较

    PHP public访问修饰符 示例: <?php header("content-type:text/html;charset=utf-8"); // BaseClass class pub { public $tag_line = "北冥有鱼!"; function display() { echo $this->tag_line."<br/>"; } } // 子类 class child extends ···

    HTML5 Convas APIs方法详解

    ☆ canvas.getContext('2d') 不可在convas中直接绘图,必须用该方法获得其二维空间绘图上 下文。 ☆ context.beginPath() 表示开始新的路径绘制。 ☆ context.isPointInPath(x, y) 判断某个点是否在路径上。在坐标系被转换后该方法不适用。 ☆ context.moveTo(x,y) 相当于将画笔从···

    WordPress主题Green-Park-2导航栏修改技巧

    我网上找了很多解决导航方案的问题,均无法用于WordPress3.1之上,总会出现其他问题。而我所讲解的这种方法是最实用、简单的。如果你用的不是本款主题,你同样可以使用此方法。 首先,以本站示列,本站主题采用Green Park 2 0.9.502最新版主题。Green Park的最新版本无···

    yii2局部关闭(开启)csrf的验证的实例代码

    上一节主要是简单地说了一下关于yii2的防御csrf的攻击机制,接下来说一下关于如何全局和局部的开启使用csrf。 (1)全局使用,我们直接在配置文件中设置enableCookieValidation为true request => [ 'enableCookieValidation' => true, ] 如果不需要使用csrf的话,···

    织梦模板DEDECMS不显示未审核tag标签文档的的方法

    未审核文档的TAG会显示在TAG列表页面, 固然点击进入TAG时, 相关的未审核文章不会显示出来, 这样对用户体验是很不好的. DEDECMS暂时没有提供这个功能,所以要解决这个问题, 让DEDECMS不显示未审核文档的TAG, 就要修改TAG的显示库文件 tag.lib.php。 方法一 打开 /i···

    JS重学系列之聊聊new操作符

    new操作符的基本过程: 1.创建一个新的空对象。 2.将构造函数的作用域赋给它(即this指向它)。 3.新对象增加构造函数的基本方法和属性。 4.返回新对象 上面的过程大家应该都熟悉,本文是重学 JS 系列的第一篇文章,写这个系列的初衷也是为了夯实自己的 JS 基础。既然是重学,···

    babel7.x和webpack4.x配置vue项目的方法步骤

    很偶然的今天想开个自己的小项目,记录一下最近项目工程上实现的一个小交互。按照之前运行非常流畅的配置走一遍,打包遇到各种坑。只好根据命令行的报错逐个排查,发现babel升级了一个大版本,已经到7.x了。看来每日沉迷项目,已经跟不上节奏了。这里记录一下遇到的问题以及解···

    PHP基于迭代实现文件夹复制、删除、查看大小等操作的方法

    本文实例讲述了PHP基于迭代实现文件夹复制、删除、查看大小等操作的方法。分享给大家供大家参考,具体如下: 前面一篇 PHP递归实现文件夹的复制、删除、查看大小操作 分析了递归操作使用技巧,这里再来分析一下迭代的操作技巧。 “既然递归能很好的解决,为什么还要用迭代呢”?···

    php cookie 详解使用实例

    下面首先为大家介绍一下cookie概念及工作原理。 什么是 Cookie? Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递。用户每次访问站点时,Web 应用程序都可以读取 Cookie 包含的信息。 Cookie 的基本工作原理 如果用户再次访问站点上的页面,浏览···