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:
// 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
andapp.onShow
when the app is created. Subsequently when WebView initialization completes, the Worker thread receives a notification from WebView thread and then invokespage.onLoad
andpage.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 functionpage.onUnload
is called for page destroying.
Object Attribute Description
Attribute | Type | Description | Minimum version |
data | Object | Function | Function for initializing data or returning initialized data | - |
events | Object | Event handler object | 1.13.7 |
onLoad | Function(query: Object) | Trigger on page loading | - |
onShow | Function | Trigger on page showing | - |
onReady | Function | Trigger on completion of initial page rendering | - |
onHide | Function | Trigger on page hiding | - |
onUnload | Function | Trigger on page unloading | - |
onShareAppMessage | Function(options: Object) | Trigger on clicking upper-right corner share | - |
onTitleClick | Function | Trigger on clicking title | - |
onOptionMenuClick | Function | Trigger on clicking extra icon of navigation bar | 1.3.0 |
onPopMenuClick | Function | Trigger on clicking custom menu buttons in upper-right general menu | 1.3.0 |
onPullDownRefresh | Function({from: manual | code }) | Trigger on pulling down page | - |
onPullIntercept | Function | Trigger on pulling down interruption | 1.11.0 |
onTabItemTap | Function | Trigger on clicking tabItem | 1.11.0 |
onPageScroll | Function({scrollTop}) | Trigger on page scrolling | - |
onReachBottom | Function | Trigger on pulling page till bottom | - |
Others | Any | The 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
Page({
data: { arr:[] },
doIt() {
this.setData({arr: [...this.data.arr, 1]});
},
});
Set as page exclusive data (not recommended)
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:
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¶meter name=parameter value…"
Attribute | Type | Description |
query | Object | Parameter 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
Attribute | Type | Description |
from | String | Click source |
pagePath | String | Page path of the clicked tabItem |
text | String | Button text of the clicked tabItem |
index | Number | Number 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:
Event | Type | Description | Lowest version |
onBack | Function | Trigger on page returning | 1.13.7 |
onKeyboardHeight | Function | Trigger on keyboard height changing | 1.13.7 |
onOptionMenuClick | Function | Trigger on clicking upper-right corner menu button | 1.13.7 |
onPopMenuClick | Function | Trigger on clicking upper-right corner general menu button | 1.13.7 |
onPullIntercept | Function | Trigger on pulling down interruption | 1.13.7 |
onPullDownRefresh | Function({from: manual/code}) | Trigger on pulling down page | 1.13.7 |
onTitleClick | Function | Trigger on clicking title | 1.13.7 |
onTabItemTap | Function | Trigger on click non-current tabItem | 1.13.7 |
beforeTabItemTap | Function | Trigger before click non-current tabItem | 1.13.7 |
onResize | Function({size: {windowWidth: number, windowHeight: number}}) | Trigger on window size changing | 1.16.0 |
Sample code:
// 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:
- It is invalid to modify
this.data
directly, which will not change the page status and will cause data inconsistency.
- Only the JSON supported data is supported.
- Try not to set too many data once.
- Do not set any value in the data as undefined, otherwise, that item will not be set, and potential issue may arise.
Sample code:
<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>
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:
Event | Type | Description | Lowest version |
data | Object | Data to be changed | - |
callback | Function | Callback function, to be executed on completion of page rendering and update | 1.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].message
, a.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:
<!-- pages/index/index.axml -->
<view class="spliceData">
<view a:for="{{a.b}}" key="{{item}}" style="border:1px solid red">
{{item}}
</view>
</view>
// pages/index/index.js
Page({
data: {
a: {
b: [1,2,3,4],
},
},
onLoad(){
this.$spliceData({ 'a.b': [1, 0, 5, 6] });
},
});
Page output:
1
5
6
2
3
4
Parameter description:
Event | Type | Description |
data | Object | Data to be changed |
callback | Function | Callback 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:
Event | Type | Description |
callback | Function | The data operation in the callback function will be updated in batch. |
Sample code:
// 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);
},
});
<!-- pages/index/index.axml -->
<view>{{counter}}</view>
<button onTap="plus">+2</button>
- In this example, page
counter
adds 2 on each button clicking.
- The
setData
is placed within this.$batchedUpdates. Thus, only one data transfer happens despite of multiplesetData
.
Page.route
Path of Page
, mapping the path value configured in app.json, type String
This is a read-only attribute.
Page({
onShow() {
// Map the path value configured in app.json
console.log(this.route)
}
})