Page
简介
Page
代表应用的一个页面,负责页面展示和交互。每个页面对应一个子目录,一般有多少个页面,就有多少个子目录。它也是一个构造函数,用来生成页面实例。
页面初始化时,需要提供数据将作为页面的第一次渲染。
<view>{{title}}</view>
<view>{{array[0].user}}</view>
Page({
data: {
title: 'Alipay',
array: [{user: 'li'}, {user: 'zhao'}]
}
})
定义交互行为时,需要在页面脚本里面指定响应函数。
<view onTap="handleTap">click me</view>
上面模板定义用户点击时,调用 handleTap
方法。
Page({
handleTap() {
console.log('yo! view tap!')
}
})
页面重新渲染,需要在页面脚本里面调用this.setData
方法。
<view>{{text}}</view>
<button onTap="changeText"> Change normal data </button>
上面代码指定用户触摸按钮时,调用changeText
方法。
Page({
data: {
text: 'init data',
},
changeText() {
this.setData({
text: 'changed data'
})
},
})
上面代码中,changeText
方法里面调用this.setData
方法,会导致页面的重新渲染。
Page(Object)
Page()
接受一个 object
作为参数,该参数用来指定页面的初始数据、生命周期函数、事件处理函数等。
//index.js
Page({
data: {
title: "Alipay"
},
onLoad(query) {
// 页面加载
},
onShow() {
// 页面显示
},
onReady() {
// 页面加载完成
},
onHide() {
// 页面隐藏
},
onUnload() {
// 页面被关闭
},
onTitleClick() {
// 标题被点击
},
onPullDownRefresh() {
// 页面被下拉
},
onReachBottom() {
// 页面被拉到底部
},
onShareAppMessage() {
// 返回自定义分享信息
},
viewTap() {
// 事件处理
this.setData({
text: 'Set data for updat.'
})
},
go() {
// 带参数的跳转,从 page/index 的 onLoad 函数的 query 中读取 xx
my.navigateTo({url:'/page/index?xx=1'})
},
customData: {
hi: 'alipay'
}
})
Object参数说明
上面代码中,Page()
方法的参数对象说明如下:
属性 | 类型 | 描述 | 最低版本 |
---|---|---|---|
data | Object or Function | 初始数据或返回初始化数据的函数 | |
events | Object | 事件处理函数集合 | 1.13.6 |
onLoad | Function(query: Object) | 页面加载时触发 | |
onShow | Function | 页面显示时触发 | |
onReady | Function | 页面初次渲染完成时触发 | |
onHide | Function | 页面隐藏时触发 | |
onUnload | Function | 页面卸载时触发 | |
onShareAppMessage | Function | 点击右上角分享时触发 | |
onTitleClick | Function | 点击标题触发 | |
onOptionMenuClick | Function | 点击导航栏额外图标触发 | 1.3.0 |
onPopMenuClick | Function | 1.3.0 | |
onPullDownRefresh | Function({from: manual /code }) | 页面下拉时触发 | |
onPullIntercept | Function | 下拉截断时触发 | 1.11.0 |
onTabItemTap | Function | 点击tabItem 时触发 | 1.11.0 |
onPageScroll | Function({scrollTop}) | 页面滚动时触发 | |
onReachBottom | Function | 上拉触底时触发 | |
其他 | Any | 开发者可以添加任意的函数或属性到 object 参数中,在页面的函数中可以用 this 来访问 |
注意:data 为对象时,如果你在页面中修改 data 则会影响该页面的不同实例。
(1)生命周期方法的说明
- onLoad: 页面加载。一个页面只会调用一次,query 参数为
my.navigateTo
和my.redirectTo
中传递的query
对象。 - onShow: 页面显示。每次页面显示都会调用一次。
- onReady: 页面初次渲染完成。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。对界面的设置,如
my.setNavigationBar
请在onReady
之后设置。 - onHide: 页面隐藏。当
my.navigateTo
到其他页面或底部tab
切换时调用。 - onUnload: 页面卸载。当
my.redirectTo
或my.navigateBack
到其他页面的时候调用。
Page.events 说明
为了使代码更加简洁,新的事件处理函数会通过Page.events
开放,原有事件跟直接在page
实例上暴露的处理函数等价。Page.events
从1.13.6
开始支持。
事件 | 类型 | 描述 | 最低版本 |
---|---|---|---|
onBack | Function | 页面返回时触发 | 1.13.6 |
onKeyboardHeight | Function | 键盘高度变化时触发 | 1.13.6 |
onOptionMenuClick | Function | 点击导航栏额外图标触发 | 1.13.6 |
onPopMenuClick | Function | 1.13.6 | |
onPullIntercept | Function | 下拉截断时触发 | 1.13.6 |
onPullDownRefresh | Function({from: manual /code }) | 页面下拉时触发 | 1.13.6 |
onTitleClick | Function | 点击标题触发 | 1.13.6 |
onTabItemTap | Function | 点击且切换tabItem 后触发 | 1.13.6 |
beforeTabItemTap | Function | 点击但切换tabItem 前触发 | 1.13.6 |
事件处理函数的说明
- onPullDownRefresh: 下拉刷新。监听用户下拉刷新事件,需要在
app.json
的window
选项中开启pullRefresh
,当处理完数据刷新后,my.stopPullDownRefresh
可以停止当前页面的下拉刷新。 - onShareAppMessage: 用户分享,详见分享。
Page.prototype.setData()
setData
函数用于将数据从逻辑层发送到视图层,同时改变对应的this.data
的值。
注意:
- 直接修改
this.data
无效,无法改变页面的状态,还会造成数据不一致。 - 请尽量避免一次设置过多的数据。
setData
接受一个对象作为参数。对象的键名key
可以非常灵活,以数据路径的形式给出,如array[2].message
、a.b.c.d
,并且不需要在this.data
中预先定义。自1.7.0
版本开始,setData
可以接受传递一个回调函数,该回调函数会在页面渲染之后执行。
下面是示例代码。
<view>{{text}}</view>
<button onTap="changeTitle"> Change normal data </button>
<view>{{array[0].text}}</view>
<button onTap="changeArray"> Change Array data </button>
<view>{{object.text}}</view>
<button onTap="changePlanetColor"> Change Object data </button>
<view>{{newField.text}}</view>
<button onTap="addNewKey"> Add new data </button>
<view>hello: {{name}}</view>
<button onTap="changeName"> Chane name </button>
Page({
data: {
text: 'test',
array: [{text: 'a'}],
object: {
text: 'blue'
},
name: 'taobao',
},
changeTitle() {
// 错误!不要直接去修改 data 里的数据
// this.data.text = 'changed data'
// 正确
this.setData({
text: 'ha'
})
},
changeArray() {
// 可以直接使用数据路径来修改数据
this.setData({
'array[0].text':'b'
})
},
changePlanetColor(){
this.setData({
'object.text': 'red'
});
},
addNewKey() {
this.setData({
'newField.text': 'c'
})
},
changeName() {
this.setData({
name: 'alipay',
}, () => { // 接受传递回调函数
console.log(this) // this 当前页面实例
this.setData({ name: this.data.name + ', ' + 'welcome!'})
})
},
})
注意:setData回调函数自1.7.0之后才支持, 可以使用
my.canIUse('page.setData.callback')
做兼容处理
Page.prototype.$spliceData()
$spliceData
同样用于将数据从逻辑层发送到视图层,但是相比于setData
,在处理长列表的时候,其具有更高的性能。
$spliceData
接受一个对象作为参数。
- 对象的键名
key
可以非常灵活,以数据路径的形式给出,如array[2].message
、a.b.c.d
,并且不需要在this.data
中预先定义。 - 对象的
value
为一个数组(格式:[start, deleteCount, …items]),数组的第一个元素为操作的起始位置,第二个元素为删除的元素的个数,剩余的元素均为插入的数据。对应es5
中数组的splice
方法
示例代码如下:
<!-- page.axml -->
<view class="spliceData">
<view a:for="{{a.b}}" key="{{item}}" style="border:1px solid red">
{{item}}
</view>
</view>
// page.js
Page({
data: {
a: {
b: [1,2,3,4]
}
},
onLoad(){
this.$spliceData({ 'a.b': [1, 0, 5, 6] })
},
})
页面输出:
1
5
6
2
3
4
注意:$spliceData自1.7.2之后才支持,可以使用
my.canIUse('page.$spliceData')
做兼容处理。
getCurrentPages()
getCurrentPages()
函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。下面代码可以用于检测当前页面栈是否具有5层页面深度。
if(getCurrentPages().length === 5) {
my.redirectTo('/xx');
} else {
my.navigateTo('/xx');
}
注意:不要尝试修改页面栈,会导致路由以及页面状态错误。
框架以栈的形式维护了当前的所有页面。 当发生路由切换的时候,页面栈的表现如下:
路由方式 | 页面栈表现 |
---|---|
初始化 | 新页面入栈 |
打开新页面 | 新页面入栈 |
页面重定向 | 当前页面出栈,新页面入栈 |
页面返回 | 当前页面出栈 |
Tab 切换 | 页面全部出栈,只留下新的 Tab 页面 |
page.json
每一个页面也可以使用[page名].json
文件来对本页面的窗口表现进行配置。
页面的配置比app.json
全局配置简单得多,只能设置window
相关的配置项,所以无需写window
这个键。注意,页面配置会覆盖app.json
的window
属性中的配置项。
格外支持 optionMenu
配置导航图标,点击后触发 onOptionMenuClick
文件 | 类型 | 必填 | 描述 |
---|---|---|---|
optionMenu | Object | 否 | 基础库 1.3.0+ 支持,设置导航栏格外图标,目前支持设置属性 icon,值为图标 url(以 https/http 开头)或 base64 字符串,大小建议 30*30 |
例如:
{
"optionMenu": {
"icon": "https://img.alicdn.com/tps/i3/T1OjaVFl4dXXa.JOZB-114-114.png"
}
}
page 样式
每个页面中的根元素为 page,需要设置高度或者背景色时,可以利用这个元素。
page {
background-color: #fff;
}
页面生命周期
下图是小程序page实例的生命周期。
Tips
- 如果想滚动页面到指定位置,请参考API滚动
- 不要修改 page.data
如果直接修改 page.data,例如
Page({
data: { arr:[] },
doIt() {
this.data.arr.push(1);
this.setData({arr: this.data.arr});
}
});
由于 data 为对象时为所有页面共享,因此如果该页面 back 后再次进入则显示为上一次的数据
可以使用不可变数据或者变更 data 为页面独有
不可变数据
Page({
data: { arr:[] },
doIt() {
this.setData({arr: [...this.data.arr, 1]});
},
});
页面独有数据(不推荐)
Page({
data() { return { arr:[] }; },
doIt() {
this.data.arr.push(1);
this.setData({arr: this.data.arr});
}
});