Page

简介

Page代表应用的一个页面,负责页面展示和交互。每个页面对应一个子目录,一般有多少个页面,就有多少个子目录。它也是一个构造函数,用来生成页面实例。

页面初始化时,需要提供数据将作为页面的第一次渲染。

  1. <view>{{title}}</view>
  2. <view>{{array[0].user}}</view>
  1. Page({
  2. data: {
  3. title: 'Alipay',
  4. array: [{user: 'li'}, {user: 'zhao'}]
  5. }
  6. })

定义交互行为时,需要在页面脚本里面指定响应函数。

  1. <view onTap="handleTap">click me</view>

上面模板定义用户点击时,调用 handleTap 方法。

  1. Page({
  2. handleTap() {
  3. console.log('yo! view tap!')
  4. }
  5. })

页面重新渲染,需要在页面脚本里面调用this.setData方法。

  1. <view>{{text}}</view>
  2. <button onTap="changeText"> Change normal data </button>

上面代码指定用户触摸按钮时,调用changeText方法。

  1. Page({
  2. data: {
  3. text: 'init data',
  4. },
  5. changeText() {
  6. this.setData({
  7. text: 'changed data'
  8. })
  9. },
  10. })

上面代码中,changeText方法里面调用this.setData方法,会导致页面的重新渲染。

Page(Object)

Page() 接受一个 object 作为参数,该参数用来指定页面的初始数据、生命周期函数、事件处理函数等。

  1. //index.js
  2. Page({
  3. data: {
  4. title: "Alipay"
  5. },
  6. onLoad(query) {
  7. // 页面加载
  8. },
  9. onShow() {
  10. // 页面显示
  11. },
  12. onReady() {
  13. // 页面加载完成
  14. },
  15. onHide() {
  16. // 页面隐藏
  17. },
  18. onUnload() {
  19. // 页面被关闭
  20. },
  21. onTitleClick() {
  22. // 标题被点击
  23. },
  24. onPullDownRefresh() {
  25. // 页面被下拉
  26. },
  27. onReachBottom() {
  28. // 页面被拉到底部
  29. },
  30. onShareAppMessage() {
  31. // 返回自定义分享信息
  32. },
  33. viewTap() {
  34. // 事件处理
  35. this.setData({
  36. text: 'Set data for updat.'
  37. })
  38. },
  39. go() {
  40. // 带参数的跳转,从 page/index 的 onLoad 函数的 query 中读取 xx
  41. my.navigateTo({url:'/page/index?xx=1'})
  42. },
  43. customData: {
  44. hi: 'alipay'
  45. }
  46. })

Object参数说明

上面代码中,Page()方法的参数对象说明如下:
属性类型描述最低版本
dataObject or Function初始数据或返回初始化数据的函数
eventsObject事件处理函数集合1.13.6
onLoadFunction(query: Object)页面加载时触发
onShowFunction页面显示时触发
onReadyFunction页面初次渲染完成时触发
onHideFunction页面隐藏时触发
onUnloadFunction页面卸载时触发
onShareAppMessageFunction点击右上角分享时触发
onTitleClickFunction点击标题触发
onOptionMenuClickFunction点击导航栏额外图标触发1.3.0
onPopMenuClickFunction1.3.0
onPullDownRefreshFunction({from: manual/code})页面下拉时触发
onPullInterceptFunction下拉截断时触发1.11.0
onTabItemTapFunction点击tabItem时触发1.11.0
onPageScrollFunction({scrollTop})页面滚动时触发
onReachBottomFunction上拉触底时触发
其他Any开发者可以添加任意的函数或属性到 object 参数中,在页面的函数中可以用 this 来访问

注意:data 为对象时,如果你在页面中修改 data 则会影响该页面的不同实例。

(1)生命周期方法的说明

  • onLoad: 页面加载。一个页面只会调用一次,query 参数为 my.navigateTomy.redirectTo 中传递的 query 对象。
  • onShow: 页面显示。每次页面显示都会调用一次。
  • onReady: 页面初次渲染完成。一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。对界面的设置,如 my.setNavigationBar 请在 onReady 之后设置。
  • onHide: 页面隐藏。当 my.navigateTo 到其他页面或底部 tab 切换时调用。
  • onUnload: 页面卸载。当 my.redirectTomy.navigateBack 到其他页面的时候调用。

Page.events 说明

为了使代码更加简洁,新的事件处理函数会通过Page.events开放,原有事件跟直接在page实例上暴露的处理函数等价。Page.events1.13.6开始支持。
事件类型描述最低版本
onBackFunction页面返回时触发1.13.6
onKeyboardHeightFunction键盘高度变化时触发1.13.6
onOptionMenuClickFunction点击导航栏额外图标触发1.13.6
onPopMenuClickFunction1.13.6
onPullInterceptFunction下拉截断时触发1.13.6
onPullDownRefreshFunction({from: manual/code})页面下拉时触发1.13.6
onTitleClickFunction点击标题触发1.13.6
onTabItemTapFunction点击且切换tabItem后触发1.13.6
beforeTabItemTapFunction点击但切换tabItem前触发1.13.6

事件处理函数的说明

  • onPullDownRefresh: 下拉刷新。监听用户下拉刷新事件,需要在 app.jsonwindow 选项中开启pullRefresh,当处理完数据刷新后,my.stopPullDownRefresh可以停止当前页面的下拉刷新。
  • onShareAppMessage: 用户分享,详见分享

Page.prototype.setData()

setData函数用于将数据从逻辑层发送到视图层,同时改变对应的this.data的值。

注意:

  • 直接修改this.data无效,无法改变页面的状态,还会造成数据不一致。
  • 请尽量避免一次设置过多的数据。
    setData接受一个对象作为参数。对象的键名key可以非常灵活,以数据路径的形式给出,如 array[2].messagea.b.c.d,并且不需要在this.data中预先定义。自1.7.0版本开始,setData可以接受传递一个回调函数,该回调函数会在页面渲染之后执行。

下面是示例代码。

  1. <view>{{text}}</view>
  2. <button onTap="changeTitle"> Change normal data </button>
  3. <view>{{array[0].text}}</view>
  4. <button onTap="changeArray"> Change Array data </button>
  5. <view>{{object.text}}</view>
  6. <button onTap="changePlanetColor"> Change Object data </button>
  7. <view>{{newField.text}}</view>
  8. <button onTap="addNewKey"> Add new data </button>
  9. <view>hello: {{name}}</view>
  10. <button onTap="changeName"> Chane name </button>
  1. Page({
  2. data: {
  3. text: 'test',
  4. array: [{text: 'a'}],
  5. object: {
  6. text: 'blue'
  7. },
  8. name: 'taobao',
  9. },
  10. changeTitle() {
  11. // 错误!不要直接去修改 data 里的数据
  12. // this.data.text = 'changed data'
  13. // 正确
  14. this.setData({
  15. text: 'ha'
  16. })
  17. },
  18. changeArray() {
  19. // 可以直接使用数据路径来修改数据
  20. this.setData({
  21. 'array[0].text':'b'
  22. })
  23. },
  24. changePlanetColor(){
  25. this.setData({
  26. 'object.text': 'red'
  27. });
  28. },
  29. addNewKey() {
  30. this.setData({
  31. 'newField.text': 'c'
  32. })
  33. },
  34. changeName() {
  35. this.setData({
  36. name: 'alipay',
  37. }, () => { // 接受传递回调函数
  38. console.log(this) // this 当前页面实例
  39. this.setData({ name: this.data.name + ', ' + 'welcome!'})
  40. })
  41. },
  42. })

注意:setData回调函数自1.7.0之后才支持, 可以使用

  1. my.canIUse('page.setData.callback')

兼容处理

Page.prototype.$spliceData()

$spliceData同样用于将数据从逻辑层发送到视图层,但是相比于setData,在处理长列表的时候,其具有更高的性能

$spliceData接受一个对象作为参数。

  • 对象的键名key可以非常灵活,以数据路径的形式给出,如 array[2].messagea.b.c.d,并且不需要在this.data中预先定义。
  • 对象的value为一个数组(格式:[start, deleteCount, …items]),数组的第一个元素为操作的起始位置,第二个元素为删除的元素的个数,剩余的元素均为插入的数据。对应es5中数组的splice方法
    示例代码如下:
  1. <!-- page.axml -->
  2. <view class="spliceData">
  3. <view a:for="{{a.b}}" key="{{item}}" style="border:1px solid red">
  4. {{item}}
  5. </view>
  6. </view>
  1. // page.js
  2. Page({
  3. data: {
  4. a: {
  5. b: [1,2,3,4]
  6. }
  7. },
  8. onLoad(){
  9. this.$spliceData({ 'a.b': [1, 0, 5, 6] })
  10. },
  11. })

页面输出:

  1. 1
  2. 5
  3. 6
  4. 2
  5. 3
  6. 4

注意:$spliceData自1.7.2之后才支持,可以使用

  1. my.canIUse('page.$spliceData')

兼容处理。

getCurrentPages()

getCurrentPages()函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。下面代码可以用于检测当前页面栈是否具有5层页面深度。

  1. if(getCurrentPages().length === 5) {
  2. my.redirectTo('/xx');
  3. } else {
  4. my.navigateTo('/xx');
  5. }

注意:不要尝试修改页面栈,会导致路由以及页面状态错误。

框架以栈的形式维护了当前的所有页面。 当发生路由切换的时候,页面栈的表现如下:

路由方式页面栈表现
初始化新页面入栈
打开新页面新页面入栈
页面重定向当前页面出栈,新页面入栈
页面返回当前页面出栈
Tab 切换页面全部出栈,只留下新的 Tab 页面

page.json

每一个页面也可以使用[page名].json文件来对本页面的窗口表现进行配置。

页面的配置比app.json全局配置简单得多,只能设置window相关的配置项,所以无需写window这个键。注意,页面配置会覆盖app.jsonwindow属性中的配置项。

格外支持 optionMenu 配置导航图标,点击后触发 onOptionMenuClick

文件类型必填描述
optionMenuObject基础库 1.3.0+ 支持,设置导航栏格外图标,目前支持设置属性 icon,值为图标 url(以 https/http 开头)或 base64 字符串,大小建议 30*30

例如:

  1. {
  2. "optionMenu": {
  3. "icon": "https://img.alicdn.com/tps/i3/T1OjaVFl4dXXa.JOZB-114-114.png"
  4. }
  5. }

page 样式

每个页面中的根元素为 page,需要设置高度或者背景色时,可以利用这个元素。

  1. page {
  2. background-color: #fff;
  3. }

页面生命周期

下图是小程序page实例的生命周期。

page lifecycle

Tips

  • 如果想滚动页面到指定位置,请参考API滚动
  • 不要修改 page.data
    如果直接修改 page.data,例如
  1. Page({
  2. data: { arr:[] },
  3. doIt() {
  4. this.data.arr.push(1);
  5. this.setData({arr: this.data.arr});
  6. }
  7. });

由于 data 为对象时为所有页面共享,因此如果该页面 back 后再次进入则显示为上一次的数据

可以使用不可变数据或者变更 data 为页面独有

不可变数据

  1. Page({
  2. data: { arr:[] },
  3. doIt() {
  4. this.setData({arr: [...this.data.arr, 1]});
  5. },
  6. });

页面独有数据(不推荐)

  1. Page({
  2. data() { return { arr:[] }; },
  3. doIt() {
  4. this.data.arr.push(1);
  5. this.setData({arr: this.data.arr});
  6. }
  7. });

原文: https://docs.alipay.com/mini/framework/page