一个小程序可以有很多页面,每个页面承载不同的功能,页面之间可以互相跳转。
Page页面
文件构成和路径
一个页面是分三部分组成:界面、配置和逻辑。
界面由WXML文件和WXSS文件来负责描述,配置由JSON文件进行描述,页面逻辑则是由JS脚本文件负责。
一个页面的文件需要放置在同一个目录
下,其中WXML文件和JS文件是必须存在的,JSON和WXSS文件是可选的。
页面路径需要在小程序代码根目录app.json中的pages字段声明
,否则这个页面不会被注册到宿主环境(首次加载会默认加载所有JS文件)中。
默认pages字段的第一个页面路径为小程序的首页
。
{
"pages":[
"pages/index/page", // 第一项默认为首页
"pages/other/other"
]
}
注册页面
有两种方式:
- 使用 Page 构造器注册页面
- 使用 Component 构造器构造页面
使用 Page 构造器注册页面
宿主环境提供了 Page() 构造器用来注册一个小程序页面,Page()在页面脚本page.js中调用。
//index.js
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// 页面创建时执行
},
onShow: function() {
// 页面出现在前台时执行
},
onReady: function() {
// 页面首次渲染完毕时执行
},
onHide: function() {
// 页面从前台变为后台时执行
},
onUnload: function() {
// 页面销毁时执行
},
onPullDownRefresh: function() {
// 触发下拉刷新时执行
},
onReachBottom: function() {
// 页面触底时执行
},
onShareAppMessage: function () {
// 页面被用户分享时执行
},
onPageScroll: function() {
// 页面滚动时执行
},
onResize: function() {
// 页面尺寸变化时执行
},
onTabItemTap(item) {
// tab 点击时执行
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// 事件响应函数
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
}, function() {
// this is setData callback
})
},
// 自由数据
customData: {
hi: 'MINA'
}
})
- data属性是当前页面WXML模板中可以用来做数据绑定的
初始数据
- onLoad / onReady / onShow / onHide /onUnload 5个回调是Page实例的
生命周期函数
- onPullDownRefresh / onReachBottom / onShareAppMessage / onPageScroll 4个回调是页面的
用户行为
使用 Component 构造器构造页面
Page 构造器适用于简单的页面。但对于复杂的页面, Page 构造器可能并不好用。
此时,可以使用 Component 构造器来构造页面。 Component 构造器的主要区别是:方法需要放在 methods: { } 里面。
Component({
data: {
text: "This is page data."
},
methods: {
onLoad: function(options) {
// 页面创建时执行
},
onPullDownRefresh: function() {
// 下拉刷新时执行
},
// 事件响应函数
viewTap: function() {
// ...
}
}
})
这种创建方式非常类似于 自定义组件 ,可以像自定义组件一样使用 behaviors 等高级特性。
在页面中使用 behaviors
页面可以引用 behaviors 。 behaviors 可以用来让多个页面有相同的数据字段和方法。
// my-behavior.js
module.exports = Behavior({
data: {
sharedText: 'This is a piece of data shared between pages.'
},
methods: {
sharedMethod: function() {
this.data.sharedText === 'This is a piece of data shared between pages.'
}
}
})
// page-a.js
var myBehavior = require('./my-behavior.js')
Page({
behaviors: [myBehavior],
onLoad: function() {
this.data.sharedText === 'This is a piece of data shared between pages.'
}
})
生命周期和打开参数
页面初次加载的时候,微信客户端就会给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方法会被调用。
我们可以看到,Page的生命周期是由微信客户端根据用户操作主动触发的。为了避免程序上的混乱,我们不应该在其他代码中主动调用Page实例的生命周期函数。
由于逻辑层和渲染层工作于两个线程,所以这里需要涉及到线程间通信问题,别忘记了第三者Native。
这里需要知道分别从两个线程的角度去看一些问题。
-
View线程,也就是渲染层
1)First Render
,初次渲染
,调用一次
2)Rerender
,再次渲染
,调用多次 -
AppService Thread线程,也就是逻辑层
1)Send Initial Data
,初始化数据,也就是在Page页面data
里面初次定义的字段和数据,会和 First Render挂钩在一起;
2)Send Data
,再次设置数据,也就是经过page js处理后动态修改数据展示(记住,是通过setData去修改,越小颗粒度性能越好),会和 Rerender挂钩在一起
3)需要关注生命周期函数的切换过程,onLoad、onShow、OnReady、OnHide、onUnload
data 是页面第一次渲染使用的初始数据。
页面加载时,data 将会以JSON
字符串的形式由逻辑层传至渲染层,因此data中的数据必须是可以转成JSON的类型:字符串,数字,布尔值,对象,数组。
页面的用户行为
小程序宿主环境提供了四个和页面相关的用户行为回调:
-
下拉刷新 onPullDownRefresh
监听用户下拉刷新事件。
1)需要在app.json
的window选项中或页面配置中开启enablePullDownRefresh。
2)可以通过wx.startPullDownRefresh触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
3)当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。 -
上拉触底 onReachBottom
监听用户上拉触底事件。可以在app.json的window选项中或页面配置page.json中设置触发距离onReachBottomDistance。在触发距离内滑动期间,本事件只会被触发一次。 -
页面滚动 onPageScroll
监听用户滑动页面事件,参数为 Object,包含 scrollTop 字段,表示页面在垂直方向已滚动的距离(单位px)。 -
用户转发 onShareAppMessage
监听用户点击页面内转发按钮(button 组件 open-type=“share”)或右上角菜单“转发”按钮的行为,并自定义转发内容。
只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮,在用户点击转发按钮的时候会调用,此事件需要return一个Object,包含title和path两个字段,用于自定义转发内容。
Page({
onShareAppMessage: function (res) {
if (res.from === 'button') {
// 来自页面内转发按钮
console.log(res.target)
}
return {
title: '自定义转发标题',
path: '/page/user?id=123'
}
}
})