小程序的宿主环境

程序与页面

微信客户端在打开小程序之前,会把整个小程序的代码包下载到本地。

紧接着通过 app.jsonpages 字段就可以知道你当前小程序的所有页面路径:

1
2
3
4
5
6
{
"pages":[
"pages/index/index",
"pages/logs/logs"
]
}

这个配置说明在 QuickStart 项目定义了两个页面,分别位于 pages/index/indexpages/logs/logs。而写在 pages 字段的第一个页面就是这个小程序的首页(打开小程序看到的第一个页面)。

于是微信客户端就把首页的代码装载进来,通过小程序底层的一些机制,就可以渲染出这个首页。

小程序启动之后,在 app.js 定义的 App 实例的 onLaunch 回调会被执行:

1
2
3
4
5
App({
onLaunch: function () {
// 小程序启动之后 触发
}
})

程序

程序构造器App()

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

  2. // other.js
    var appInstance = getApp()
    App() 的调用方式如代码清单3-4所示,App构造器接受一个Object参数,参数说明如表3-1所示,其中onLaunch / onShow / onHide 三个回调是App实例的生命周期函数,我们会在后文展开;onError我们暂时不在本章展开,我们会在第8章里详细讨论;App的其他参数我们也放在后文进行展开

参数属性 类型 描述
onLaunch Function 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
onShow Function 当小程序启动,或从后台进入前台显示,会触发 onShow
onHide Function 当小程序从前台进入后台,会触发 onHide
onError Function 当小程序发生脚本错误,或者 API 调用失败时,会触发 onError 并带上错误信息
其他字段   任意 可以添加任意的函数或数据到 Object 参数中,在App实例回调用 this 可以访问

生命周期参数

app.js生命周期

onLaunch

当小程序初始化完成时,会触发 onLaunch(全局只触发一次)

onShow

当小程序启动,或从后台进入前台显示,会触发 onShow

onHide

当小程序从前台进入后台,会触发 onHide

onError

当小程序发生脚本错误,或者 API 调用失败时,会触发 onError 并带上错误信息

page生命周期

1
2
3
4
5
6
7
8
9
10
11
12
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() { }
})

参数属性 类型 描述
data Object 页面的初始数据
onLoad Function 生命周期函数–监听页面加载,触发时机早于onShow和onReady
onReady Function 生命周期函数–监听页面初次渲染完成
onShow Function 生命周期函数–监听页面显示,触发事件早于onReady
onHide Function 生命周期函数–监听页面隐藏
onUnload Function 生命周期函数–监听页面卸载
onPullDownRefresh Function 页面相关事件处理函数–监听用户下拉动作
onReachBottom Function 页面上拉触底事件的处理函数
onShareAppMessage Function 用户点击右上角转发
onPageScroll Function 页面滚动触发事件的处理函数
其他 Any 可以添加任意的函数或数据,在Page实例的其他函数中用 this 可以访问

小程序全局数据

1
2
3
4
5
6
7
8
9
10
11
12
我们在 3.1.2节说到小程序的JS脚本是运行在JsCore的线程里,小程序的每个页面各自有一个WebView线程进行渲染,所以小程序切换页面时,小程序逻辑层的JS脚本运行上下文依旧在同一个JsCore线程中。
在上文中说道App实例是单例的,因此不同页面直接可以通过App实例下的属性来共享数据。App构造器可以传递其他参数作为全局属性以达到全局共享数据的目的。
代码清单3-6 小程序全局共享数据

// app.js
App({
globalData: 'I am global data' // 全局共享数据
})
// 其他页面脚本other.js
var appInstance = getApp()
console.log(appInstance.globalData) // 输出: I am global data
与此同时,我们要特别留意一点,所有页面的脚本逻辑都跑在同一个JsCore线程,页面使用setTimeout或者setInterval的定时器,然后跳转到其他页面时,这些定时器并没有被清除,需要开发者自己在页面离开的时候进行清理。

页面page

文件构成和路径

一个页面是分三部分组成:界面、配置和逻辑。界面由WXML文件和WXSS文件来负责描述,配置由JSON文件进行描述,页面逻辑则是由JS脚本文件负责。

路径

页面路径需要在小程序代码根目录app.json中的pages字段声明,否则这个页面不会被注册到宿主环境中。例如两个页面的文件的相对路径分别为 pages/index/page. 和 pages/other/other. (表示wxml/wxss/json/js四个文件),在app.json的pages字段的代码路径需要去除.后缀,如代码清单3-7所示,默认pages字段的第一个页面路径为小程序的首页。

app.json声明页面路径

1
2
3
4
5
6
7
app.json声明页面路径
{
"pages":[
"pages/index/page", // 第一项默认为首页
"pages/other/other"
]
}

页面构造器Page()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
https://developers.weixin.qq.com/ebook?action=get_post_info&docid=0004eec99acc808b00861a5bd5280a
宿主环境提供了 Page() 构造器用来注册一个小程序页面,Page()在页面脚本page.js中调用,Page() 的调用方式如代码清单3-8所示。Page构造器接受一个Object参数,参数说明如表3-4所示,其中data属性是当前页面WXML模板中可以用来做数据绑定的初始数据,我们会在后文展开讨论;onLoad / onReady / onShow / onHide /onUnload 5个回调是Page实例的生命周期函数,我们在后文展开;onPullDownRefresh / onReachBottom / onShareAppMessage / onPageScroll 4个回调是页面的用户行为,我们也会在后文展开。
代码清单3-8 Page构造器

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() { }
})

技术贴
https://www.cnblogs.com/fozero/p/7868560.html

对页面进行监听 参数

1
2
3
4
5
6
7
8
9
10
11
data	Object	页面的初始数据
onLoad Function 生命周期函数--监听页面加载,触发时机早于onShow和onReady
onReady Function 生命周期函数--监听页面初次渲染完成
onShow Function 生命周期函数--监听页面显示,触发事件早于onReady
onHide Function 生命周期函数--监听页面隐藏
onUnload Function 生命周期函数--监听页面卸载
onPullDownRefresh Function 页面相关事件处理函数--监听用户下拉动作
onReachBottom Function 页面上拉触底事件的处理函数
onShareAppMessage Function 用户点击右上角转发
onPageScroll Function 页面滚动触发事件的处理函数
其他 Any 可以添加任意的函数或数据,在Page实例的其他函数中用 this 可以访问

页面的数据

1
2
3
4
5
6
7
8
9
10
11
<!-- page.wxml -->
<view>{{text}}</view>
<view>{{array[0].msg}}</view>

// page.js
Page({
data: {
text: 'init data',
array: [{msg: '1'}, {msg: '2'}]
}
})

操作数据 setData

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 setData(data, callback)
setData(数据, 回调函数)
<!-- page.wxml -->
<view>{{text}}</view>
<view>{{array[0].msg}}</view>

// page.js
Page({
data: {
text: 'init data',
array: [{msg: '1'}, {msg: '2'}]
}
})
// page.js
Page({
onLoad: function(){
this.setData({
text: 'change data'
}, function(){
// 在这次setData对界面渲染完毕后触发
})
}
})

// page.js
Page({
data: {
a: 1, b: 2, c: 3,
d: [1, {text: 'Hello'}, 3, 4]
}
onLoad: function(){
// a需要变化时,只需要setData设置a字段即可
this.setData({a : 2})
}
})

此外需要注意以下3点:

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

页面的用户行为

下拉刷新 onPullDownRefresh

1
2
下拉刷新 onPullDownRefresh
监听用户下拉刷新事件,需要在app.json的window选项中或页面配置page.json中设置enablePullDownRefresh为true。当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。

上拉触底 onReachBottom

1
2
上拉触底 onReachBottom
监听用户上拉触底事件。可以在app.json的window选项中或页面配置page.json中设置触发距离onReachBottomDistance。在触发距离内滑动期间,本事件只会被触发一次。

页面滚动 onPageScroll

1
2
页面滚动 onPageScroll
监听用户滑动页面事件,参数为 Object,包含 scrollTop 字段,表示页面在垂直方向已滚动的距离(单位px)。

用户转发 onShareAppMessage

1
2
3
4
5
6
7
8
9
10
11
12
13
只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮,在用户点击转发按钮的时候会调用,此事件需要return一个Object,包含title和path两个字段,用于自定义转发内容,如代码清单3-13所示。

代码清单3-13 使用onShareAppMessage自定义转发字段

// page.js
Page({
onShareAppMessage: function () {
return {
title: '自定义转发标题',
path: '/page/user?id=123'
}
}
})

页面跳转和路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
一个小程序拥有多个页面,我们可以通过wx.navigateTo推入一个新的页面,如图3-6所示,在首页使用2次wx.navigateTo后,页面层级会有三层,我们把这样的一个页面层级称为页面栈。

后续为了表述方便,我们采用这样的方式进行描述页面栈:[ pageA, pageB, pageC ],其中pageA在最底下,pageC在最顶上,也就是用户所看到的界面,需要注意在本书编写的时候,小程序宿主环境限制了这个页面栈的最大层级为10层 ,也就是当页面栈到达10层之后就没有办法再推入新的页面了。我们下面来通过上边这个页面栈描述以下几个和导航相关的API。
使用 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进行页面跳转。。


{
"tabBar": {
"list": [
{ "text": "Tab1", "pagePath": "pageA" },
{ "text": "Tab1", "pagePath": "pageF" },
{ "text": "Tab1", "pagePath": "pageG" }
]
}
}

小程序的宿主环境
http://www.dwyblog.cn/2022/01/20/小程序的宿主环境/
作者
幸福来敲门
发布于
2022年1月20日
许可协议