在第一次接触小程序的App环境时在网上找教程,通常都是几句话带过,但是在这里面会有很多的数据处理以及业务逻辑,苦找无奈,最后通过看文档进行了一些实用总结,希望能帮到大家。

        在App.js文件中我们可以接受一个Object参数注册小程序,指定小程序的生命周期,或者是设置全局变量等。

        首先介绍globalData,在globalData中定义的数值或者是对象是可以被全局访问的,比如:

// app.js
App({
    globalData:{
        msg: 'hello'
    }
})

//other.js
const app = getApp()
console.log(app.globalData.msg)   // hello

        再就是介绍小程序的生命周期,需要注意的是这和页面的生命周期不太一样,页面的生命周期不多赘述,本文详细介绍App构造器。

                                                         常用小程序生命周期

                                                    常用小程序具体页面生命周期

        初次进入小程序的时候,微信客户端初始化好宿主环境,同时从网络下载或者从本地缓存中拿到小程序的代码包,把它注入到宿主环境,初始化完毕后,微信客户端就会给App实例派发onLaunch事件,App构造器参数所定义的onLaunch方法会被调用。
       进入小程序之后,用户可以点击右上角的关闭,或者按手机设备的Home键离开小程序,此时小程序并没有被直接销毁,这种情况可以被称为“小程序进入后台状态”,App构造器参数所定义的onHide方法会被调用。
       当再次回到微信或者再次打开小程序时,微信客户端会把“后台”的小程序唤醒,这种情况可以被称为“小程序进入前台状态”,App构造器参数所定义的onShow方法会被调用。
       可以看到,App的生命周期是由微信客户端根据用户操作主动触发的。为了避免程序上的混乱不应该从其他代码里主动调用App实例的生命周期函数。
       在微信客户端中打开小程序有很多途径:从群聊会话里打开,从小程序列表中打开,通过微信扫一扫二维码打开,从另外一个小程序打开当前小程序等,针对不同途径的打开方式,小程序有时需要做不同的业务处理,所以微信客户端会把打开方式带给onLaunch和onShow的调用参数options。通常我们可以在不同页面之间进行跳转的时候将参数通过options进行传递,通过App.js向页面A进行跳转,如果携带的参数不一样,最终的呈现结果就不一样。这句话很重要。

       在业务逻辑方面,app.js的onLaunch生命周期中负责发布某个方法,但不负责具体细节的处理

       现在假设你需要在使用小程序的时候进行接口的调用,不同的页面在调用接口后有不同的处理。

       面对这个业务你会怎么做呢?是直接在不同的页面中进行请求吗?这样可以,但是不同页面的命名方法就需要你记得特别牢固,不然命名千奇百怪,不方便后期的维护。此时就可以利用App构造器来发布任务了。在小程序调用完接口后直接使用一个函数this.apiReadyCallback()表示这个命名函数负责处理调用接口完毕后的一些工作,接下来到目标页面中通过getApp().apiReadyCallback(){.......}进行逻辑的操作。

        话虽如此,我在彻底理解之前有一个疑问,为什么在App.js文件中直接就能点出apiReadyCallback这个函数呢?不是还没有定义吗?

        这就又涉及到另外一个概念了。

        小程序的运行环境分成渲染层和逻辑层, WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端做中转,逻辑层发送网络请求也经由Native转发。讲人话就是一个小程序可以有多个页面,但是只使用了一个逻辑层JsCore,不同页面使用的逻辑App是相同的。

        因此,在App.js文件中作为任务的分发使用了一个在该页面中未出现过的函数,其实是在其他页面getApp()拿到App构造器后进行了详细定义。

        这种分布任务的方法似乎只能用在请求数据的回调中,这应该涉及到了App.js生命周期和页面生命周期加载快慢的问题,如果直接发布任务的话会报错,我认为是App比测试页面更先渲染完成了,此时页面中定义的 app.test = () => {....} 还未执行导致App未拿到函数实体。

        

        经测验,在request请求过程中发布任务,或者是在定时器中发布任务都是可行的。

// App.js
App({
  onLaunch () {
    // 方法一:请求时发布任务
    const that = this
    // 这里我对wx.request进行过Promise封装,直接用wx.request也可行
    request('/personalized',{ type:2 },'GET')
     .then((res)=>{
       that.test(123); // 获取个人信息完毕后的回调函数
    })

    // 方法二:添加定时器方法,伪造请求延迟,等待测试页面先将函数定义完毕
    setTimeout(() => {
      this.test(123)
    }, 1000);

    // 方法三:直接调用 x
    this.test(123)    // 会报错
  }
})

// test.js
onLoad: function (options) {
    const app = getApp()
    app.test = res => {
      console.log('mytest....' + res);
    }
},

// 当页面跳转至test.wxml时控制台输出 mytest....123

该方法似乎只能用一次,待了解后再提出解决办法。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐