- 微信小程序:開發入門及案例詳解
- 李駿 邊思
- 2706字
- 2019-01-04 18:58:55
2.4.2 頁面邏輯文件(JavaScript)
頁面邏輯文件主要功能有:設置初始化數據,注冊當前頁面生命周期函數,注冊事件處理函數等。小程序的邏輯層文件是JavaScript文件,所有的邏輯文件,包括app.js,最終將會打包成一個js文件,在小程序啟動時運行,直到小程序銷毀,類似于ServiceWorker,所以邏輯層也稱為App Service。
在小程序中,每個邏輯文件有獨立的作用域,并具備模塊化能力。由于JavaScript邏輯文件是運行在純JavaScript引擎中而并非運行在瀏覽器中,一些瀏覽器提供的特有對象,如document、window等,在小程序中都無法使用,同理,一些基于document、window的框架如:jQuery、Zepto都不能在小程序中使用,同時我們不能通過操作DOM改變頁面,這時需要我們將面向DOM操作的編程思路轉化為數據綁定和事件響應。
1.注冊頁面
在頁面邏輯文件中需要通過Page()函數注冊頁面,指定頁面的初始數據、生命周期函數、事件處理函數等,參數為一個Object對象,其屬性如下:
□data:頁面的初始數據,數據格式必須是可轉成JSON格式的對象類型。當頁面第一次渲染時,data會以JSON的形式由邏輯層傳至渲染層,渲染層可以通過WXML對數據進行綁定。
□onLoad:生命周期函數,頁面加載時觸發。一個頁面只會調用一次,接受頁面參數,可以獲取wx.navigateTo、wx.redirectTo以及<navigator/>中的query參數。
□onShow:生命周期函數,頁面顯示時觸發。每次打開頁面都會調用一次。
□onReady:生命周期函數,頁面初次渲染完成時觸發。一個頁面生命周期中只會調用一次,代表當前頁面已經準備妥當,可以和視圖層進行交互。一些對界面的設置,操作需要在頁面準備妥當后調用,如wx.setNavigationBarTitle需要在onReady之后設置,詳細可以參考后面的“頁面生命周期”小節。
□onHide:生命周期函數,頁面隱藏時觸發。
□onUnload:生命周期函數,頁面卸載時觸發。
□onPullDownRefresh:頁面相關時間處理函數,用戶下拉時觸發。使用時需要將app. json配置中window的enablePullDownRefresh屬性設置為true。當處理完數據刷新后,可以調用wx.stopPullDownRefresh方法停止當前頁面的下拉刷新。
□onReachBottom:頁面上拉觸底事件的處理函數。
□其他:開發者可以添加任意的函數或數據到Object參數中,可以用this訪問這些函數和數據。
示例代碼如代碼清單2-2所示:
代碼清單2-2 頁面邏輯文件
// 獲取app實例 var app = getApp(); Page( { data : { // 頁面初始化數據 count : 0 }, onLoad : function() { // 頁面加載時執行 }, onShow : function() { // 頁面打開時執行 console.log( app.globalData ); }, onReady : function() { // 頁面初次渲染完成執行,一個頁面只會調用一次 }, onHide : function() { // 頁面隱藏時執行 }, onUnload : function() { // 頁面卸載時執行 }, onPullDownRefresh : function() { // 下拉刷新時執行 }, onReachBottom : function() { // 下拉觸底時執行 }, // 自定義函數,可與渲染層中的組件進行事件綁定 countClick : function() { // 觸發視圖層重新渲染 this.setData( { count : this.data.count + 1 } ); }, // 自定義數據 customData : { name : ’微信’ } } );
頁面的生命周期函數比小程序的生命周期函數略微復雜一點,弄懂其執行順序能避免在不恰當的生命周期函數中調用還未創建的對象或方法,小程序框架以棧的形式維護了當前的所有頁面,當發生路由切換時,頁面棧和生命周期函數的關系如下:
□小程序初始化:默認頁面入棧,依次觸發默認頁面onLoad、onShow、onReady方法。
□打開新頁面:新頁面入棧,依次觸發新頁面onLoad、onShow、onReady方法。
□頁面重定向:當前頁面出棧并卸載,觸發當前頁面onUnload方法,新頁面入棧,觸發新頁面onLoad、onShow、onReady方法。
□頁面返回:頁面不斷出棧并卸載,觸發當前彈出頁面onUnload方法,直到返回目標頁面,新頁面入棧,觸發新頁面onShow方法。
□Tab切換:當前頁面出棧但不卸載,僅觸發onHide方法,新頁面入棧,如果當前頁面是新加載的,觸發onLoad、onShow、onReady方法,如果當前頁面已加載過,僅觸發onShow方法。
□程序從前臺到后臺:觸發當前頁面onHide方法,觸發App onHide方法。
□程序從后臺到前臺:觸發小程序onShow方法,觸發頁面onShow方法。
整體來說,如果頁面在生命周期中,只會觸發onShow和onLoad方法,只有加載和卸載時才會觸發onLoad、onReady和onUnload方法,而觸發頁面卸載只有頁面返回和頁面重定向兩種操作。頁面生命周期函數的執行順序不用死記硬背,開發過程中可以開啟app. json中的debug模式,路由切換時,小程序、頁面的生命周期函數執行順序都會在控制臺以info形式輸出,在后面小節中我們將對頁面生命周期作簡單介紹。
2.獲取當前頁面棧
有注冊就有獲取,getCurrentPages()函數便是用于獲取當前頁面棧的實例,頁面棧以數組形式按棧順序給出,第一個元素為首頁,最后一個元素為當前頁面。不要嘗試修改頁面棧,這會導致路由以及頁面狀態錯誤。
示例代碼如下:
/* 獲取頁面棧 */ var pages = getCurrentPages(); /* 獲取當前頁面對象 */ var currentPage = pages[pages.length - 1];
3.事件處理函數
頁面對象中注冊的函數可以和視圖層中的組件進行綁定,當達到觸發條件時,就會執行Page中定義的相應事件,這類自定義函數統稱為事件處理函數。小程序中組件的事件分為通用事件和特殊事件,事件類型請參考后面2.4.3節中“事件”小節。
示例代碼如下:
<view bindtap= "myevent ">點擊執行邏輯層事件</view> Page( { myevent : function() { console.log( ’點擊了view' ); } } );
4.觸發視圖層渲染
頁面首次加載時,框架會結合初始化數據渲染頁面,在邏輯層中則需主動調用Page.
prototype.setData()方法,而不能直接修改Page的data值,這樣不僅無法觸發視圖層渲染,還會造成數據不一致。當Page.prototype.setData()被調用時,會將數據從邏輯層發送到視圖層觸發視圖層重繪,同時會修改Page的data值。setData()接受一個Object對象參數,方法會自動將this.data中的key對應的值變成Object參數中key對應的值。當Object參數key對應的值和this.data中key對應的值一致時,將不會觸發視圖層渲染。在項目中我們一定要保證視圖層和邏輯層的數據一致。
Object參數的key值非常靈活,可以按數據路徑的形式給出,如array[5].info、obj.key.subkey,并且這樣使用時,不需要在this.data中預先定義。
示例代碼如下:
<view>{{text}}</view> <button bindtap="changeText">修改普通數據</button> <view>{{object.subObject.objectText}}</view> <button bindtap="changeObjectText">修改對象數據</button> <view>{{array[0].arrayText}}</view> <button bindtap="changeArrayText">修改數組數據</button> <view>{{newField.newFieldText}}</view> <button bindtap="addNewData">添加新字段</button> Page( { data : { text : 'normal data', object : { subObject : { objectText : 'object data' } }, array : [ { arrayText : 'array data' } ] }, changeText : function() { this.setData( { /* 普通索引 */ text : 'new normal data' } ); }, changeObjectText : function() { this.setData( { /* 按路徑索引 */ 'object.subObject.objectText' : 'new object data' } ); }, changeArrayText : function() { this.setData( { /* 按路徑索引 */ 'array[0].arrayText' : 'new array data' } ); }, addNewData : function() { this.setData( { /* 修改一個已綁定,但未在data中定義的數據 */ 'newField.newFieldText' : 'add new data' } ); } } );
5.頁面生命周期
頁面的生命周期整體關系著頁面視圖層線程和頁面邏輯層線程,注冊頁面時,Object參數中很多屬性都是生命周期函數,這些函數的調用和頁面生命息息相關,程序視圖層線程和邏輯層線程關系如圖2-8所示。

圖2-8 Page實例的生命周期
如圖2-8,線程啟動后視圖層和邏輯層相互監聽,當邏輯層線程觸發onLoad、onShow方法后會把初始數據data傳送給視圖層線程,視圖層完成第一次渲染后觸發邏輯層onReady方法,代表頁面已經準備妥當,之后我們便可通過setData方法主動觸發視圖層渲染。當頁面被調往后臺時,觸發onHide方法,這時邏輯層線程并沒有銷毀,我們仍然可以通過代碼控制視圖層渲染,只是可能不會在界面上表現出來。當頁面從后臺回到前臺時,觸發onShow方法,最后當頁面銷毀時,觸發onUnload方法。整體來看onLoad、onReady和onUnload方法在生命周期中只會調用一次,生命周期內顯示、隱藏頁面都是觸發onShow和onHide方法,在路由方式中,只有頁面重定向和頁面返回會結束當前頁面生命周期,當進入一個已加載的頁面時只會觸發onShow方法,不會觸發onLoad和onReady方法。