《微信小程序七日談》系列文章:html
本系列的文章並不是初學教程,而是筆者在具體開發過程當中遇到的問題以及部分解決方案。前端
前兩篇文章第一天:人生若只如初見和次日:你可能要拋棄原來的響應式開發思惟零零散散地記錄了一些微信小程序的細節,主要集中在UI方面。其中提到的解決方案只是筆者自身的一些探索,並不是最佳實踐,甚至不是筆者項目中最後採用的方案(最終方案會在後續文章裏詳細講述)。其實小程序的UI開發並不是簡短的兩篇文章能夠歸納的,還有許多細節待挖掘,奈何項目排期緊張,暫時就不去研究與當前需求無關的東西了。vue
今天這篇文章簡單記錄一下在使用小程序Page組件時對於其生命週期的一些使用心得。json
官方文檔對Page的生命週期的介紹簡單明瞭,在生命週期的不一樣階段拋出的鉤子函數依次爲: onLoad
-> onShow
-> onReady
-> onHide
-> onUnload
。小程序
使用過React的開發者確定會對用on
作爲鉤子函數命名前綴很是不舒服,React使用will、did、should等一系列有時態語義的詞彙命名鉤子函數,令開發者一眼就能分辨鉤子函數對應的生命週期階段。可是on
是具備必定歧義的。瀏覽器的用戶行爲事件機制,以及咱們所熟悉的jQuery中,使用on做爲捕獲/監聽事件的API命名,這種情形下能夠把on理解爲當某件事情發生時作某些行爲,這也是大部分前端工程師對on語義的理解。這種理解的on有一層攔截的意思,好比onclick
先於<a>
的href
跳轉,能夠攔截其默認的click行爲,在默認click以前發生。可是請你們仔細思考一下window.onload
中on
的含義。onload
的觸發時機是在文檔加載完成以後,在執行咱們定義的onload邏輯以前,文檔已經完成了load行爲。也就是說,onload
並無攔截load行爲,而是在load事件以後發生。因此,on
這個詞彙並不能精準的形容究竟是前仍是後,它是沒有時態語義的。微信小程序
具體到Page的生命週期鉤子函數,你們請憑第一感受理解下面幾個函數的執行時機:瀏覽器
onLoad
onShow
onReady
我相信大部分人對於這三者的理解是:鉤子函數在load/show/ready完成以後執行。跟window.onload
是同樣的。那麼請你們在思考下列兩個的執行時機:微信
onHide
onUnload
跟前三者是同樣的嗎?前端工程師
咱們先不去探究後二者與前三者的執行時機策略是否相同。請你們先以常規的思惟思考下列的應用場景:app導航欄左上角有個「返回」按鈕,以下圖:
app
很常見的一個邏輯是:若是用戶在未保存表單數據以前點擊返回按鈕的話,一般會彈出一個提示層,以下:
也就是說,頁面有個beforeUserLeave
的策略,在執行userLeave
以前進行攔截並給出提示,以避免用戶的操做失誤。這不只僅是業務邏輯的需求,也是一個網站從開始到被關閉過程當中的一環,這就是咱們熟知的window.onbeforeunload
事件。
一樣,筆者參與的項目也有上述的業務邏輯,在用戶離開頁面以前提示用戶的編輯狀態。對應小程序的幾個鉤子函數,結合React和Vue的開發經驗,天然而然地就想到在onHide
或者onUnload
內攔截返回操做並給出提示。
可是,並不行!onHide
和onUnload
的執行時機策略居然跟onLoad/onShow/onReady
同樣!
也就是說,在page被卸載以後纔會執行onUnload
。這就形成用戶點擊返回按鈕,已經回到了上一個頁面,而後,忽然彈出了一個提示框:
用戶:WTF?
其實官方文檔詳細展現了Page的各個鉤子函數的執行時機,以下圖:
從上圖中能夠看出:
onHide
是在當前Page被「set to background」以後觸發;onUnload
是在當前Page被「destory」以後觸發。固然,每一個人設計組件時對組件的生命週期都有本身的理解和實現,並非說小程序的Page生命週期設計的很差,只是但願可以提供更細化的鉤子函數,好比上文提到的「before」策略,以便實現更人性化的用戶體驗。
vue.js的1.x版本提供了activate鉤子函數,這個鉤子阻塞了組件的後續執行,方便開發者在組件渲染以前進行特殊處理,好比使用jsonp請求數據,成功後執行done()
觸發組件的後續流程。
小程序裏有沒有阻塞的鉤子函數呢?
可能大部分人跟筆者同樣,第一個想法就是試試onShow
是不是阻塞的,可是結果並不像預期的那樣。小程序的Page組件沒有提供阻塞的鉤子函數,根據上文中的官方配圖能夠看到,在組件的data更新以後有個"Rerender"
動做。Page組件的數據統一爲data
,而不是像React或者Vue區分props
和state/data
。這種設計的優勢是不用特地的對某個data進行監聽,data所有是動態的,這意味着任何一個data的改變都會觸發Rerender。
小程序提供一些內置的UI組件,可是邏輯組件只有app
和page
兩種,而且二者並非嚴格的父子組件關係。因此,page
組件並不須要相似React中的props
數據,全部的數據都屬於自身。
Page組件的生命週期十分簡潔,上手容易。可是面對一些特殊需求時並不能提供很好的支持。這種狀況下咱們不得不適當地修改需求邏輯。
小程序中並無父子組件的關係譜,組件的數據不會區分props
和state
,所有是統一的data
,而且所有是動態的。任何data的修改都會觸發Rerender。
最近發現有些網站、我的博客以及微信公衆號未經受權轉載了筆者的文章,做爲技術人員,但願你們都具備基本的職業道德。剽竊的技術是不會獲得尊重的,對於未經受權的轉載方,必要的時候會付諸法律手段。