小程序学习笔记(四)程序与页面

从逻辑组成来说,一个小程序是由多个“页面”组成的“程序”,下面介绍小程序中程序和页面的概念以及它们的生命周期

1.程序

“小程序”指的是产品层面的程序,而“程序”指的是代码层面的程序实例,为了避免误解,下文采用App来代替代码层面的“程序”概念

(1)程序构造器App()

宿主环境提供了 App() 构造器用来注册一个程序App,需要留意的是App() 构造器必须写在项目根目录的app.js里,App实例是单例对象,在其他JS脚本中可以使用宿主环境提供的 getApp() 来获取程序实例。App构造器接受一个Object参数:

App({
  onLaunch: function(options) {},
  onShow: function(options) {},
  onHide: function() {},
  onError: function(msg) {},
  globalData: 'I am global data'
})

 globalData是全局变量,可以存放一些所有页面需要使用的公共变量。

(2)程序的生命周期和打开场景

初次进入小程序的时候,微信客户端初始化好宿主环境,同时从网络下载或者从本地缓存中拿到小程序的代码包,把它注入到宿主环境,初始化完毕后,微信客户端就会给App实例派发onLaunch事件,App构造器参数所定义的onLaunch方法会被调用。

进入小程序之后,用户可以点击左上角的关闭,或者按手机设备的Home键离开小程序,此时小程序并没有被直接销毁,我们把这种情况称为“小程序进入后台状态”,App构造器参数所定义的onHide方法会被调用。

当再次回到微信或者再次打开小程序时,微信客户端会把“后台”的小程序唤醒,我们把这种情况称为“小程序进入前台状态”,App构造器参数所定义的onShow方法会被调用。

我们可以看到,App的生命周期是由微信客户端根据用户操作主动触发的。为了避免程序上的混乱,我们不应该从其他代码里主动调用App实例的生命周期函数。

在微信客户端中打开小程序有很多途径:从群聊会话里打开,从小程序列表中打开,通过二维码打开等,针对不同途径的打开方式,小程序有时需要做不同的业务处理,所以微信客户端会把打开方式带给onLaunch和onShow的调用参数options

小程序的JS脚本是运行在JsCore的线程里,小程序的每个页面各自有一个WebView线程进行渲染,所以小程序切换页面时,小程序逻辑层的JS脚本运行上下文依旧在同一个JsCore线程中。App实例是单例的,因此不同页面直接可以通过App实例下的属性来共享数据。App构造器可以传递其他参数作为全局属性以达到全局共享数据的目的。

特别留意一点,所有页面的脚本逻辑都跑在同一个JsCore线程,页面使用setTimeout或者setInterval的定时器,然后跳转到其他页面时,这些定时器并没有被清除,需要自己在页面离开的时候进行清理。

2.页面

一个小程序可以有很多页面,每个页面承载不同的功能,页面之间可以互相跳转。

(1)页面文件构成和路径

每一个页面是分三部分组成:界面、配置和逻辑界面由WXML文件和WXSS文件来负责描述,配置由JSON文件进行描述,页面逻辑则是由JS脚本文件负责一个页面的文件需要放置在同一个目录下,其中WXML文件和JS文件是必须存在的,JSON和WXSS文件是可选的

页面路径需要在小程序代码根目录app.json中的pages字段声明,否则这个页面不会被注册到宿主环境中

{
  "pages":[
    "pages/index/page", // 第一项默认为首页
    "pages/other/other"
  ]
}

(2)页面构造器Page()

宿主环境提供了 Page() 构造器用来注册一个小程序页面,Page()在页面脚本page.js中调用,Page构造器接受一个Object参数,参数说明如下图所示,其中data属性是当前页面WXML模板中可以用来做数据绑定的初始数据

Page({
  data: { text: "This is page data." },
  onLoad: function(options) { },
  onReady: function() { },
  onShow: function() { },
  onHide: function() { },
  onUnload: function() { },
  onPullDownRefresh: function() { },
  onReachBottom: function() { },
  onShareAppMessage: function () { },
  onPageScroll: function() { }
})

(3)页面的生命周期和打开参数

页面初次加载的时候,微信客户端就会给Page实例派发onLoad事件,Page构造器参数所定义的onLoad方法会被调用,onLoad在页面没被销毁之前只会触发1次,在onLoad的回调中,可以获取当前页面所调用的打开参数option

页面显示之后,Page构造器参数所定义的onShow方法会被调用,一般从别的页面返回到当前页面时,当前页的onShow方法都会被调用。

在页面初次渲染完成时,Page构造器参数所定义的onReady方法会被调用,onReady在页面没被销毁前只会触发1次,onReady触发时,表示页面已经准备妥当,在逻辑层就可以和视图层进行交互了。

以上三个事件触发的时机是onLoad早于 onShow,onShow早于onReady

页面不可见时,Page构造器参数所定义的onHide方法会被调用,这种情况会在使用wx.navigateTo切换到其他页面、底部tab切换时触发。

当前页面使用wx.redirectTo或wx.navigateBack返回到其他页时,当前页面会被微信客户端销毁回收,此时Page构造器参数所定义的onUnload方法会被调用。

页面的打开参数query,用于携带页面跳转时新页面需要的上一个页面的数据。小程序把页面的打开路径定义成页面URL,其组成格式和网页的URL类似,在页面路径后使用英文 ? 分隔path和query部分,query部分的多个参数使用 & 进行分隔,参数的名字和值使用 key=value 的形式声明。

(4)页面的数据

页面Page构造器的data字段,data参数是页面第一次渲染时从逻辑层传递到渲染层的数据。宿主环境所提供的Page实例的原型中有setData函数,我们可以在Page实例下的方法调用this.setData把数据传递给渲染层,从而达到更新界面的目的。

由于小程序的渲染层和逻辑层分别在两个线程中运行,所以setData传递数据实际是一个异步的过程,所以setData的第二个参数是一个callback回调,在这次setData对界面渲染完毕后触发。

此外需要注意以下3点:

  1. 直接修改 Page实例的this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
  2. 由于setData是需要两个线程的一些通信消耗,为了提高性能,每次设置的数据不应超过1024kB。
  3. 不要把data中的任意一项的value设为undefined,否则可能会有引起一些不可预料的bug。

(5)页面的用户行为

  1. 下拉刷新 onPullDownRefresh
    监听用户下拉刷新事件,需要在app.json的window选项中或页面配置page.json中设置enablePullDownRefresh为true。当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。
  2. 上拉触底 onReachBottom
    监听用户上拉触底事件。可以在app.json的window选项中或页面配置page.json中设置触发距离onReachBottomDistance。在触发距离内滑动期间,本事件只会被触发一次。
  3. 页面滚动 onPageScroll
    监听用户滑动页面事件,参数为 Object,包含 scrollTop 字段,表示页面在垂直方向已滚动的距离(单位px)。
  4. 用户转发 onShareAppMessage
    只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮,在用户点击转发按钮的时候会调用,此事件需要return一个Object,包含title和path两个字段,用于自定义转发内容。

(6)页面跳转和路由

一个小程序拥有多个页面,我们可以通过wx.navigateTo推入一个新的页面,在首页使用2次wx.navigateTo后,页面层级会有三层,我们把这样的一个页面层级称为页面栈。最大深度为10.

页面栈:[ pageA, pageB, pageC ],其中pageA在最底下,pageC在最顶上,也就是用户所看到的界面

使用 wx.navigateTo({ url: 'pageD' }) 可以往当前页面栈多推入一个 pageD,此时页面栈变成 [ pageA, pageB, pageC, pageD ]。
使用 wx.navigateBack() 可以退出当前页面栈的最顶上页面,此时页面栈变成 [ pageA, pageB, pageC ]。
使用wx.redirectTo({ url: 'pageE' }) 是替换当前页变成pageE,此时页面栈变成 [ pageA, pageB, pageE ],当页面栈到达10层没法再新增的时候,往往就是使用redirectTo这个API进行页面跳转。

wx.switchTab({ url: 'pageF' })用于切换tab页,此时上一个tab页的页面栈会被清空,wx.navigateTo和wx.redirectTo只能打开非TabBar页面,wx.switchTab只能打开Tabbar页面。

 

参考资料:

《小程序开发指南》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值