一個小程序可以有很多頁面,每個頁面承載不同的功能,頁面之間可以互相跳轉。
Page頁面
文件構成和路徑
一個頁面是分三部分組成:界面、配置和邏輯。
界面由WXML文件和WXSS文件來負責描述,配置由JSON文件進行描述,頁面邏輯則是由JS腳本文件負責。
一個頁面的文件需要放置在同一個目錄
下,其中WXML文件和JS文件是必須存在的,JSON和WXSS文件是可選的。
頁面路徑需要在小程序代碼根目錄app.json中的pages字段聲明
,否則這個頁面不會被註冊到宿主環境(首次加載會默認加載所有JS文件)中。
默認pages字段的第一個頁面路徑爲小程序的首頁
。
{
"pages":[
"pages/index/page", // 第一項默認爲首頁
"pages/other/other"
]
}
註冊頁面
有兩種方式:
- 使用 Page 構造器註冊頁面
- 使用 Component 構造器構造頁面
使用 Page 構造器註冊頁面
宿主環境提供了 Page() 構造器用來註冊一個小程序頁面,Page()在頁面腳本page.js中調用。
//index.js
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// 頁面創建時執行
},
onShow: function() {
// 頁面出現在前臺時執行
},
onReady: function() {
// 頁面首次渲染完畢時執行
},
onHide: function() {
// 頁面從前臺變爲後臺時執行
},
onUnload: function() {
// 頁面銷燬時執行
},
onPullDownRefresh: function() {
// 觸發下拉刷新時執行
},
onReachBottom: function() {
// 頁面觸底時執行
},
onShareAppMessage: function () {
// 頁面被用戶分享時執行
},
onPageScroll: function() {
// 頁面滾動時執行
},
onResize: function() {
// 頁面尺寸變化時執行
},
onTabItemTap(item) {
// tab 點擊時執行
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// 事件響應函數
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
}, function() {
// this is setData callback
})
},
// 自由數據
customData: {
hi: 'MINA'
}
})
- data屬性是當前頁面WXML模板中可以用來做數據綁定的
初始數據
- onLoad / onReady / onShow / onHide /onUnload 5個回調是Page實例的
生命週期函數
- onPullDownRefresh / onReachBottom / onShareAppMessage / onPageScroll 4個回調是頁面的
用戶行爲
使用 Component 構造器構造頁面
Page 構造器適用於簡單的頁面。但對於複雜的頁面, Page 構造器可能並不好用。
此時,可以使用 Component 構造器來構造頁面。 Component 構造器的主要區別是:方法需要放在 methods: { } 裏面。
Component({
data: {
text: "This is page data."
},
methods: {
onLoad: function(options) {
// 頁面創建時執行
},
onPullDownRefresh: function() {
// 下拉刷新時執行
},
// 事件響應函數
viewTap: function() {
// ...
}
}
})
這種創建方式非常類似於 自定義組件 ,可以像自定義組件一樣使用 behaviors 等高級特性。
在頁面中使用 behaviors
頁面可以引用 behaviors 。 behaviors 可以用來讓多個頁面有相同的數據字段和方法。
// my-behavior.js
module.exports = Behavior({
data: {
sharedText: 'This is a piece of data shared between pages.'
},
methods: {
sharedMethod: function() {
this.data.sharedText === 'This is a piece of data shared between pages.'
}
}
})
// page-a.js
var myBehavior = require('./my-behavior.js')
Page({
behaviors: [myBehavior],
onLoad: function() {
this.data.sharedText === 'This is a piece of data shared between pages.'
}
})
生命週期和打開參數
頁面初次加載的時候,微信客戶端就會給Page實例派發onLoad事件,Page構造器參數所定義的onLoad方法會被調用,onLoad在頁面沒被銷燬之前只會觸發1次,在onLoad的回調中,可以獲取當前頁面所調用的打開參數option。
頁面顯示之後,Page構造器參數所定義的onShow方法會被調用,一般從別的頁面返回到當前頁面時,當前頁的onShow方法都會被調用。
在頁面初次渲染完成時,Page構造器參數所定義的onReady方法會被調用,onReady在頁面沒被銷燬前只會觸發1次,onReady觸發時,表示頁面已經準備妥當,在邏輯層就可以和視圖層進行交互了。
以上三個事件觸發的時機是onLoad早於 onShow,onShow早於onReady。
頁面不可見時,Page構造器參數所定義的onHide方法會被調用,這種情況會在使用wx.navigateTo切換到其他頁面、底部tab切換時觸發。
當前頁面使用wx.redirectTo或wx.navigateBack返回到其他頁時,當前頁面會被微信客戶端銷燬回收,此時Page構造器參數所定義的onUnload方法會被調用。
我們可以看到,Page的生命週期是由微信客戶端根據用戶操作主動觸發的。爲了避免程序上的混亂,我們不應該在其他代碼中主動調用Page實例的生命週期函數。
由於邏輯層和渲染層工作於兩個線程,所以這裏需要涉及到線程間通信問題,別忘記了第三者Native。
這裏需要知道分別從兩個線程的角度去看一些問題。
-
View線程,也就是渲染層
1)First Render
,初次渲染
,調用一次
2)Rerender
,再次渲染
,調用多次 -
AppService Thread線程,也就是邏輯層
1)Send Initial Data
,初始化數據,也就是在Page頁面data
裏面初次定義的字段和數據,會和 First Render掛鉤在一起;
2)Send Data
,再次設置數據,也就是經過page js處理後動態修改數據展示(記住,是通過setData去修改,越小顆粒度性能越好),會和 Rerender掛鉤在一起
3)需要關注生命週期函數的切換過程,onLoad、onShow、OnReady、OnHide、onUnload
data 是頁面第一次渲染使用的初始數據。
頁面加載時,data 將會以JSON
字符串的形式由邏輯層傳至渲染層,因此data中的數據必須是可以轉成JSON的類型:字符串,數字,布爾值,對象,數組。
頁面的用戶行爲
小程序宿主環境提供了四個和頁面相關的用戶行爲回調:
-
下拉刷新 onPullDownRefresh
監聽用戶下拉刷新事件。
1)需要在app.json
的window選項中或頁面配置中開啓enablePullDownRefresh。
2)可以通過wx.startPullDownRefresh觸發下拉刷新,調用後觸發下拉刷新動畫,效果與用戶手動下拉刷新一致。
3)當處理完數據刷新後,wx.stopPullDownRefresh可以停止當前頁面的下拉刷新。 -
上拉觸底 onReachBottom
監聽用戶上拉觸底事件。可以在app.json的window選項中或頁面配置page.json中設置觸發距離onReachBottomDistance。在觸發距離內滑動期間,本事件只會被觸發一次。 -
頁面滾動 onPageScroll
監聽用戶滑動頁面事件,參數爲 Object,包含 scrollTop 字段,表示頁面在垂直方向已滾動的距離(單位px)。 -
用戶轉發 onShareAppMessage
監聽用戶點擊頁面內轉發按鈕(button 組件 open-type=“share”)或右上角菜單“轉發”按鈕的行爲,並自定義轉發內容。
只有定義了此事件處理函數,右上角菜單纔會顯示“轉發”按鈕,在用戶點擊轉發按鈕的時候會調用,此事件需要return一個Object,包含title和path兩個字段,用於自定義轉發內容。
Page({
onShareAppMessage: function (res) {
if (res.from === 'button') {
// 來自頁面內轉發按鈕
console.log(res.target)
}
return {
title: '自定義轉發標題',
path: '/page/user?id=123'
}
}
})