Page Mechanism

Page(object: Object)

Each .js file in the /pages directory has a  Page object to define properties for a Mini Program page. We can use this object to specify the initial data, register lifecycle callbacks, and custimize event handlers.

Below are the basic page codes:

copy
// pages/index/index.js
Page({
  data: {
    title: "Mini Program",
  },
  onLoad(query) {
    // Page loading
  },
  onShow() {
    // Page showing
  },
  onReady() {
    // Page loading complete
  },
  onHide() {
    // Page hiding
  },
  onUnload() {
    // Page closed
  },
  onTitleClick() {
    // Title clicked
  },
  onPullDownRefresh() {
    // Page pulled down
  },
  onReachBottom() {
    // Page pulled down till bottom
  },
  onShareAppMessage() {
   // Return customized sharing information
  },
  // Event handler object
  events: {
    onBack() {
      console.log('onBack');
    },
  },
  // Custom event handler
  viewTap() {
    this.setData({
      text: 'Set data for update.',
    });
  },
  // Custom event handler
  go() {
    // Jump with parameters, read type from query of onLoad function in page/ui/index
    my.navigateTo({url:'/page/ui/index?type=mini'});
  },
  // Custom data object
  customData: {
    name: 'Mini Program',
  },
});

Page Lifecycle

The diagram below shows the lifecyle of the  Page object.

The Mini Program basically uses the view thread (Webview) and application service thread (Worker) for control and management. The Webview and Worker threads run in parallel.

  • Upon startup, the Worker thread invokes app.onLauch and app.onShow when the app is created. Subsequently when WebView initialization completes, the Worker thread receives a notification from WebView thread and then invokes page.onLoad and page.onShow to indicate the completion of page creation.
  • Upon the notification on completion of the Webview initialization, the Worker sends the initialized data to the Webview for render. Now the Webview completes the first data render.
  • After the first render is completed, the Webview enters into the ready status and notifies the Worker. The Worker calls the page.onReady function and enters into the active status.
  • in the active status, the Worker modifies data each time and then notifies the Webview for rendering. When switched to the background, the Worker calls the page.onHide function and enters into the suspended status. The page.onShow function will be called when  page returns to the foreground and enters into the active status. When the return or redirection page is called, the function page.onUnload is called for page destroying.

Page Mechanism

Object Attribute Description

AttributeTypeDescriptionMinimum version
dataObject | FunctionFunction for initializing data or returning initialized data-
eventsObjectEvent handler object1.13.7
onLoadFunction(query: Object)Trigger on page loading-
onShowFunctionTrigger on page showing-
onReadyFunctionTrigger on completion of initial page rendering-
onHideFunctionTrigger on page hiding-
onUnloadFunctionTrigger on page unloading-
onShareAppMessageFunction(options: Object)Trigger on clicking upper-right corner share-
onTitleClickFunctionTrigger on clicking title-
onOptionMenuClickFunctionTrigger on clicking extra icon of navigation bar1.3.0
onPopMenuClickFunctionTrigger on clicking custom menu buttons in upper-right general menu1.3.0
onPullDownRefreshFunction({from: manual| code})Trigger on pulling down page-
onPullInterceptFunctionTrigger on pulling down interruption1.11.0
onTabItemTapFunctionTrigger on clicking tabItem1.11.0
onPageScrollFunction({scrollTop})Trigger on page scrolling-
onReachBottomFunctionTrigger on pulling page till bottom-
OthersAnyThe developer can add any function or attribute column into the object. The this can be used for access in the page functions.-

Page Data Object

The initial data can be specified for the page by setting data.  When data is an object, it is shared by all pages. In other words, when it returns and then enters the page again, the last page data will be displayed instead of the initial data. In such a case, the issue may be fixed by setting data as unchanged data or changing data as page exclusive data.

Set as unchanged data

copy
Page({
 data: { arr:[] },
 doIt() {
   this.setData({arr: [...this.data.arr, 1]});
 },
});

Set as page exclusive data (not recommended)

copy
Page({
 data() { return { arr:[] }; },
 doIt() {
   this.setData({arr: [1, 2, 3]});
 },
});

Notes: Do not modify this.data directly, which will not change the page status and will cause data inconsistency.

For example:

copy
Page({
 data: { arr:[] },
 doIt() {
   this.data.arr.push(1); // Do not do this!
   this.setData({arr: this.data.arr});
 }
});

Lifecycle Function

onLoad(query: Object)

Trigger on page initializing. It called only once for each page.

The query is the query object transferred in the my.navigateTo and my.redirectTo.

The query content is in the format: "parameter name=parameter value&parameter name=parameter value…"

AttributeTypeDescription
queryObjectParameter for opening the current page path

onShow()

Trigger on page showing or switching to foreground

onReady()

Trigger on completion of initial page rendering. It is called only once for each page, indicating the page is ready and can interact with view layer. For the setting of interface such as my.setNavigationBar, please set behind onReady.

onHide()

Trigger on page hiding or switching to background. Such as my.navigateTo to another page or switching via bottom tab.

onUnload()

Trigger on page unloading. Such as my.redirectTo or my.navigateBack to another page.

Page Event Handler

onShareAppMessage(options: Object)

Trigger on clicking share button in upper-right general menu or clicking in-page share button.

onTitleClick()

Trigger on clicking title.

onOptionMenuClick()

Trigger on clicking upper-right corner menu button.

onPopMenuClick()

Trigger on clicking upper-right corner general menu button.

onPullDownRefresh({from: manual|code})

Trigger on pulling down to refresh. It is required to enable pullRefresh in the window option of app.json. When the data refresh is processed completely, call my.stopPullDownRefresh to stop the pull-to-refresh for that page.

onPullIntercept()

Trigger on pulling down interruption.

onTabItemTap(object: Object)

Trigger on clicking tabItem

AttributeTypeDescription
fromStringClick source
pagePathStringPage path of the clicked tabItem
textStringButton text of the clicked tabItem
indexNumberNumber of the clicked tabItem, starting from 0

onPageScroll({scrollTop})

Trigger on page scrolling, scrollTop is the page scrolling distance.

onReachBottom()

Trigger on pulling page till bottom.

Events

To simplify codes, a new event handler object events is available. The existing page handler is equivalent to the exposed event functions on the page instance.

Note:

  • The support for events starts from basic library version 1.13.7.
  • Please distinguish the basic library version requirements for the same named functions of the page event hander and events.

below is the list of event functions supported by events:

EventTypeDescriptionLowest version
onBackFunctionTrigger on page returning1.13.7
onKeyboardHeightFunctionTrigger on keyboard height changing1.13.7
onOptionMenuClickFunctionTrigger on clicking upper-right corner menu button1.13.7
onPopMenuClickFunctionTrigger on clicking upper-right corner general menu button1.13.7
onPullInterceptFunctionTrigger on pulling down interruption1.13.7
onPullDownRefreshFunction({from: manual/code})Trigger on pulling down page1.13.7
onTitleClickFunctionTrigger on clicking title1.13.7
onTabItemTapFunctionTrigger on click non-current tabItem1.13.7
beforeTabItemTapFunctionTrigger before click non-current tabItem1.13.7
onResizeFunction({size: {windowWidth: number, windowHeight: number}})Trigger on window size changing1.16.0

Sample code:

copy
// Feature detection 
my.canIUse('page.events.onBack');

Page({
  data: {
    text: 'This is page data.'
  },
  onLoad(){
    // trigger on page loading
  },
  events:{
    onBack(){
      // Trigger on page returning
    },
    onKeyboardHeight(e){
      // Trigger on keyboard height changing
      console.log('keyboard height:', e.height)
    },
    onOptionMenuClick(){
      // Trigger on clicking upper-right corner menu button
    },
    onPopMenuClick(e){
      // Trigger on clicking custom menu buttons in upper-right general menu
      console.log('index of the clicked custom menu', e.index)
      console.log('name of the clicked custom menu', e.name)
      console.log('menuIconUrl of the clicked custom menu', e.menuIconUrl)
    },
    onPullIntercept(){
      // Trigger on pulling down interruption
    },
    onPullDownRefresh(e){
      // Trigger on pulling down page The e.from value “code” indicates the event triggered by startPullDownRefresh; value “manual” indicates the pull-down event trigger by user
      console.log('type of triggered pull-down refresh', e.from)
      my.stopPullDownRefresh()
    },
    onTitleClick(){
      // Trigger on clicking title
    },
    onTabItemTap(e){
      // e.from means triggering after clicking tabItem and switching; value “user” indicates event triggered by user clicking; value “api” indicates event triggered by switchTab
      console.log('type of triggering tab change', e.from)
      console.log('path of page corresponding to the clicked tab', e.pagePath)
      console.log('text of the clicked tab', e.text)
      console.log('index of the clicked tab', e.index)
    },
    beforeTabItemTap(){
      // trigger on clicking tabItem but before switching
    },
    onResize(e){
      // Trigger on window size changing
      var {windowWidth, windowHeight} = e.size
      console.log('width of changed window', windowWidth)
      console.log('height of changed window', windowHeight)
    },
  }
})

Page.prototype.setData(data: Object, callback: Function)

The setData sends data from logic layer to view layer and changes the value of this.data.

The Object is expressed in the form key: Value.. The key value in this.data is changed to value. Here, the key can be flexibly provided in form of data path, such as array[2].message, a.b.c.d. It is not necessary to predefine in this.data.

The following points are worth attentions in use:

  1. It is invalid to modify this.data directly, which will not change the page status and will cause data inconsistency.
  1. Only the JSON supported data is supported.
  1. Try not to set too many data once.
  1. Do not set any value in the data as undefined, otherwise, that item will not be set, and potential issue may arise.

Sample code:

copy
<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"> Change name </button>
copy
Page({
  data: {
    text: 'test',
    array: [{text: 'a'}],
    object: {
      text: 'blue',
    },
    name: 'Mini Program',
  },
  changeTitle() {
    // Wrong! Do not modify the data directly
    // this.data.text = 'changed data'  
    
    // Correct!
    this.setData({
      text: 'ha',
    });
  },
  changeArray() {
    // Possible to modify data by using directly data path
    this.setData({
      'array[0].text': 'b',
    });
  },
  changePlanetColor(){
    this.setData({
      'object.text': 'red',
    });
  },
  addNewKey() {
    this.setData({
      'newField.text': 'c',
    });
  },
  changeName() {
    this.setData({
      name: 'Mini Program',
    }, () => { // Accept transfer of callback function
      console.log(this); // this: current page instance
      this.setData({ name: this.data.name + ', ' + 'welcome!'});
    });
  },
});

Parameter description:

EventTypeDescriptionLowest version
dataObjectData to be changed-
callbackFunctionCallback function, to be executed on completion of page rendering and update1.7.0, Use my.canIUse('page.setData.callback') for compatibility processing.

Page.prototype.$spliceData(data: Object, callback: Function)

Note: $spliceData is supported since version 1.7.2. The my.canIUse('page.$spliceData') can be used for compatibility processing.

Similarly, the spliceData is used to transfer data from logic layer to view layer, but has higher performance than setData in processing long list.

The Object is expressed in the form key: Value.. The key value in this.data is changed to value. Here, the key can be flexibly provided in form of data path, such as array[2].messagea.b.c.d. It is not necessary to predefine in this.data. The value is an array (format: [start, deleteCount, ...items]). The first element of the array is the start position of the operation, the second element is the number of elements to be deleted, and other other elements are the insertion data. It maps the array splice method in es5.

Sample code:

copy
<!-- pages/index/index.axml -->
<view class="spliceData">
  <view a:for="{{a.b}}" key="{{item}}" style="border:1px solid red">
    {{item}}
  </view>
</view>
copy
// pages/index/index.js
Page({
  data: {
    a: {
      b: [1,2,3,4],
    },
  },
  onLoad(){
    this.$spliceData({ 'a.b': [1, 0, 5, 6] });
  },
});

Page output:

copy
1
5
6
2
3
4

Parameter description:

EventTypeDescription
dataObjectData to be changed
callbackFunctionCallback function, to be executed on completion of page rendering and update

Page.prototype.$batchedUpdates(callback: Function)

Batch update data.

Note: $batchedUpdates is supported since version 1.14.0. Themy.canIUse('page.$batchedUpdates') can be used for compatibility processing.

Parameter description:

EventTypeDescription
callbackFunctionThe data operation in the callback function will be updated in batch.

Sample code:

copy
// pages/index/index.js
Page({
  data: {
    counter: 0,
  },
  plus() {
    setTimeout(() => {
      this.$batchedUpdates(() => {
        this.setData({
          counter: this.data.counter + 1,
        });
        this.setData({
          counter: this.data.counter + 1,
        });
      });
    }, 200);
  },
});
copy
<!-- pages/index/index.axml -->
<view>{{counter}}</view>
<button onTap="plus">+2</button>
  1. In this example, page counter adds 2 on each button clicking.
  1. The setData is placed within this.$batchedUpdates. Thus, only one data transfer happens despite of multiple setData.

Page.route

Path of Page, mapping the path value configured in app.json, type String

This is a read-only attribute.

copy
Page({
  onShow() {
    // Map the path value configured in app.json
    console.log(this.route)
  }
})