注册页面:
Page()
:
用来创建小程序中的一个页面。接受一个 Object 类型参数,其指定页面的初始数据、生命周期函数、事件处理函数等。
参数:
-
data:页面第一次渲染使用的初始数据。
页面加载时,data 将会以 JSON 字符串的形式由逻辑层传至渲染层,因此 data 中的数据必须是可以转成 JSON 的类型:字符串,数字,布尔值,对象,数组。
-
options:页面的组件选项。
-
behaviors:类似于 mixins 的组件间代码复用机制。
-
生命周期回调函数:
onLoad(options)
:页面初始加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数。onShow()
:页面显示/切入前台时触发。onReady()
:页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。对界面内容进行设置的 API 如
wx.setNavigationBarTitle
,需要在 onReady 中进行。
第一次加载进来时,这三个生命周期函数的顺序是onload()
-->onShow()
-->onReady()
。onHide()
:页面隐藏/切入后台时触发。如
wx.navigateTo
、底部 tab 切换到其他页面、小程序切入后台等。onUnload()
:页面卸载时触发。如
wx.redirectTo
、wx.navigateBack
到其他页面时。
-
页面事件处理函数:
onPullDownRefresh()
:监听用户下拉刷新事件。需要在
app.json
的 window 选项中或页面配置中开启 enablePullDownRefresh。
可以通过wx.startPullDownRefresh
触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
当处理完数据刷新后,wx.stopPullDownRefresh
可以停止当前页面的下拉刷新。onReachBottom()
:监听用户上拉触底事件。可以在
app.json
的 window 选项中或页面配置中设置触发距离onReachBottomDistance。
在触发距离内滑动期间,本事件只会被触发一次。onPageScroll()
:监听用户滑动页面事件。只在需要的时候才在 page 中定义此方法,不要定义空方法,以避免不必要的事件派发对渲染层-逻辑层通信的影响。
要避免在 onPageScroll 中过于频繁的执行 setData 等引起逻辑层-渲染层通信的操作,尤其是每次传输大量数据,会影响通信耗时。onResize()
:小程序屏幕旋转时触发。onTabItemTap()
:点击 tab 时触发。onShareAppMessage()
:监听用户点击页面内转发按钮(button 组件open-type="share"
)或右上角菜单“转发”按钮的行为,并自定义转发内容。只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮。
onShareTimeLine()
:监听右上角菜单“分享到朋友圈”按钮的行为,并自定义分享内容。只有定义了此事件处理函数,右上角菜单才会显示“分享到朋友圈”按钮。
onAddToFavorites()
:监听用户点击右上角收藏按钮的行为,并自定义收藏内容。
-
其他:可以添加任意的函数或数据到 Object 参数中,在页面的函数中用 this 可以访问。
Page.prototype.setData()
:
setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data
的值(同步)。
this.setData({})
和直接this.data.xxx=xxx
都会改变this.data
中的值,但是this.setData({})
会触发页面的重新渲染,this.data.xxx=xxx
不会。
参数:
- data:以对象
key: value
的形式表示,将this.data
中的 key 对应的值改变成 value。其中 key 可以是数据路径的形式(例如:数组中的某一项array[0].message
或对象的某个属性a.b.c.d
),并且不需要在this.data
中预先定义。单次设置的数据不能超过 1024 kb。
- callback:setData 引起的界面更新渲染完毕后的回调函数。
setData 的过程:
setData 的过程大致可以分成三个阶段:
- 逻辑层虚拟 DOM 树的遍历和更新,触发组件生命周期和 observer 等。
- 将 data 从逻辑层传输到视图层。
- 视图层虚拟 DOM 树的更新、真实 DOM 元素的更新并触发页面渲染更新。
合理使用 setData:
setData 容易引发性能问题。
- data 应只包括渲染相关的数据。
- 页面或组件的 data 字段,应用来存放和页面或组件渲染相关的数据(即直接在 wxml 中出现的字段)。
- 页面或组件渲染间接相关的数据可以设置为纯数据字段,使用 setData 设置并使用 observers 监听变化。
- 页面或组件渲染无关的数据,应挂在非 data 的字段下,如
this.userData = {userId: 'xxx'}
。
- 控制 setData 的频率:仅在需要进行页面内容更新时调用 setData;对连续的 setData 调用尽可能的进行合并。
- 选择合适的 setData 范围:组件的 setData 只会引起当前组件和子组件的更新,对于需要频繁更新的页面元素(例如:秒杀倒计时),可以封装为独立的组件,在组件内进行 setData 操作。
- setData 应只传发生变化的数据:尽量以数据路径形式改变数组中的某一项或对象的某个属性,而不是每次都更新整个对象或数组。
- 控制后台页面的 setData:页面切后台后的更新操作,应尽量避免或延迟到页面 onShow 后延迟进行。
由于小程序逻辑层是单线程运行的,后台页面去 setData 也会抢占前台页面的运行资源。
页面路由:
微信小程序以栈的形式维护了当前的所有页面。当发生路由切换的时候,页面栈的表现如下:
- 初始化:新页面入栈。小程序打开第一个页面时触发。打开的页面触发 onLoad 和 onShow。
- 打开新页面:新页面入栈。离开的页面触发 onHide。打开的页面触发 onLoad 和 onShow。
调用 API
wx.navigateTo()
或使用组件<navigator open-type="navigateTo"/>
时触发。 - 页面重定向:当前页面出栈,新页面入栈。离开的页面触发 onUnload,打开的页面触发 onLoad 和 onShow。
调用 API
wx.redirectTo()
或使用组件<navigator open-type="redirectTo"/>
时触发。 - 页面返回:页面不断出栈,直到目标返回页。离开的页面触发 onUnload,打开的页面触发 ononShow。
调用 API
wx.navigateBack()
或使用组件<navigator open-type="navigateBack">
,或用户按左上角返回按钮时触发。 - Tab 切换:页面全部出栈,只留下新的 Tab 页面。
调用 API
wx.switchTab()
或使用组件<navigator open-type="switchTab"/>
或用户切换 Tab 时触发。 - 重启动:页面全部出栈,只留下新的页面。离开的页面触发 onUnload,打开的页面触发 onLoad 和 ononShow。
调用 API
wx.reLaunch()
或使用组件<navigator open-type="reLaunch"/>
时触发,会销毁原页面。
Page.route
:
获取当前页面的路径,类型为 String。
Page({
onShow: function() {
console.log(this.route)
}
})
getCurrentPages()
:
获取当前页面栈。数组中第一个元素为首页,最后一个元素为当前页面。
不要尝试修改页面栈,会导致路由以及页面状态错误。
不要在App.onLaunch
的时候调用 getCurrentPages(),此时 page 还没有生成。
页面间事件通信:
如果一个页面由另一个页面通过 wx.navigateTo()
打开,这两个页面间将建立一条数据通道:
- 页面中的
wx.navigateTo()
的 success 回调中包含一个 EventChannel 对象,使用 EventChannel 对象的 emit 方法可以向被打开页面发送事件。wx.navigateTo()
中的 events 对象属性可以用于监听被打开页面发送过来的事件。 - 被打开页面通过
this.getOpenerEventChannel()
方法可以获得一个 EventChannel 对象,使用 EventChannel 对象的 emit 方法可以向上一页面发送事件,使用 EventChannel 对象的 on 方法可以监听上一页面发送过来的事件。
<!-- index.wxml -->
<button bindtap="handleNavToHome">点击跳转到 home 页</button>
// index.js
Page({
handleNavToHome: function() {
wx.navigateTo({
url: '/pages/home/home',
success: function(res) {
// 通过 eventChannel 对象的 emit 方法向被打开页面传送数据
res.eventChannel.emit('transferDataFromIndex', '我是 index 页面传递到 home 页面上的数据')
},
// 监听被打开页面传送到当前页面的数据
events: {
transferDataFromHome: function(data) {
console.log(data)
}
}
})
}
})
// home.js
Page({
onLoad(options) {
const eventChannel = this.getOpenerEventChannel()
// 通过 eventChannel 对象的 on 方法接收上一页面传送到当前页面的数据
eventChannel.on('transferDataFromIndex', function(data) {
console.log(data)
})
// 通过 eventChannel 对象的 emit 方法向上一页面传送数据
eventChannel.emit('transferDataFromHome', '我是 home 页面传递到 index 页面上的数据')
},
})