mpvue小程序開發 - 生命週期梳理

轉自IMWeb社區,做者:llunnn,原文連接前端

最近在開發小程序,嘗試性地使用了一下mpvue框架。vue

mpvue 是一個使用 Vue.js 開發小程序的前端框架。框架基於 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 實現,使其能夠運行在小程序環境中,從而爲小程序開發引入了整套 Vue.js 開發體驗。web

mpvue同時維護了Vue和小程序的兩套機制,所以須要對兩套機制進行關聯。這裏主要對mpvue的生命週期來進行一些梳理。小程序

微信小程序生命週期

首先咱們須要瞭解,微信小程序的生命週期:微信小程序

App對象,主要有onLaunch, onShow和onHide。瀏覽器

Page對象,主要有onLoad, onShow, onReady, onHide和onUnload。前端框架

Vue到mpvue

mpvue的出現使得咱們能夠用書寫Vue實例的方式去聲明這兩種對象,並使得Vue實例兼容小程序的生命週期。微信

Vue的生命週期主要體如今8個鉤子:beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeDestroy, destroyed。app

來對比一下Vue和mpvue的生命週期,看一下mpvue作出了什麼改變:框架

對比來看,mpvue主要是對created和beforeMount之間的過程作了改變。

在Vue中,這個階段主要做用是將template編譯爲render函數:

而在mpvue中,對於App或Page組件(這裏的Is App or Page component應該要解釋爲「是否爲App或Page組件」),爲他們初始化小程序的生命週期,並註冊App對象或Page對象:

這裏能夠看出來,mpvue中,Vue和小程序生命週期鉤子觸發的基本順序是beforeCreate -> created -> onLaunch/onLoad -> onShow -> onReady -> beforeMount -> mounted -> ...

實踐驗證

這裏有一個入口頁面,包含一個經過wx.navigateTo跳轉到newPage的按鈕。

newPage中包含一個card組件,和一個經過wx.navigateBack跳轉回入口頁面的按鈕。

在App, newPage和card的各個生命週期鉤子輸出信息,來觀察它們的觸發狀況和順序。

在App被建立,跳轉到newPage前

咱們能夠觀察到,app對象首先被建立,觸發onLaunch和onShow。

在這以後,newPage被create。須要注意的是,此時咱們尚未跳轉到newPage,也就是說在mpvue中,不管頁面是否被訪問到,其Vue實例的beforeCreate和created都在app建立後就被觸發。

第一次跳轉到newPage並返回入口頁面

因爲newPage頁面的beforeCreate和created已經提早被觸發過了,在調用了wx.NavigateTo跳轉到newPage時,先觸發小程序的生命週期,再觸發beforeMount,這時候開始建立子組件card的實例,按照beforeCreate -> created -> onLoad -> onReady -> beforeMount -> mounted 的順序觸發生命週期鉤子。(這裏組件的onShow爲何沒有觸發..須要再深刻探究一下)

在wx.navigateBack時,小程序的生命週期鉤子onUnload被觸發。但須要注意的是:Vue的生命週期鉤子beforeDestroy和destroyed並無被觸發,也就是說小程序中newPage的page對象被卸載了,但newPage和card的Vue實例並無被銷燬。

第二次跳轉到newPage並返回入口頁面

newPage和card都已經被create且沒有destroy,在再次wx.navigateTo時將直接從onLoad -> onShow -> onReady開始觸發,newPage的mount和update過程也會出發,而component以後update過程被觸發了。這裏能夠發現,在onLoad以後還通過了幾個階段,纔開始觸發Vue實例的生命週期鉤子,而上一次保存在內存中的數據並無被destroy,所以在從新加載的過程當中,Vue實例還保存着上一次加載頁面時的數據。

開發時遇到的問題

遇到的問題主要是由create過程在頁面加載前就被統一觸發引發的。 在使用Vue時,常常在created鉤子中得到新的data。由於此時對data的數據觀測已經被創建,可是頁面內容還沒有被掛載,Vue實例能夠觀測到data的變化並在視圖顯示出來以前改變其內容。

若是在mpvue中,咱們想獲取頁面路由query中的數據,或是想在頁面建立時請求接口,咱們可能會這樣考慮:

在created中獲取數據? 在mpvue中,created只被觸發一次,且在頁面建立前被觸發,也就是說query中的數據是沒法得到的,再次訪問頁面時若是數據發生了變化,created中的邏輯也並不會再次執行。

推遲到beforeMount? 從功能上說,在beforeMount獲取數據是沒有問題的。但因爲頁面unload時沒有觸發destroy,在再次加載頁面時,Vue實例仍然保存着前一次得到的數據,而頁面的onLoad、onShow均在beforeMount以前被觸發,實踐時會發現,頁面在數據更新以前就會被顯示出來,舊的數據會在頁面中「一閃而過」。

在onLoad中獲取數據? 實踐證實這的確是一種最穩妥的方法,數據能被正確地設置,頁面也不會「閃」。 可是官方文檔有這樣一句話: 除特殊狀況外,不建議使用小程序的生命週期鉤子。 這裏大概是爲了代碼的移植性作考慮吧,不知道這裏算不算特殊狀況呢。

使用computed? 爲了不使用小程序的生命週期鉤子,還能夠考慮使用computed的來獲取query中的內容,而query須要在頁面onLoad以後才存在,這裏須要注意作一些判斷。

總結

從Vue過分到mpvue仍是很是平滑的,特別是在有太小程序開發經驗的狀況下。可是因爲小程序自己和瀏覽器的差別,使得開發過程當中會遇到一些難以理解的問題,將生命週期作一下梳理對更順利地進行開發是有一些好處的。

可是,從這裏也能夠看到,對於開發小程序來講,mpvue實際上額外地維護了一套Vue的機制,並對小程序的事件、數據進行代理、同步,實際上這個過程可能會形成一些性能上的損耗。再加上mpvue目前仍是存在一些缺陷,而小程序也支持了數據綁定、組件化開發,我的認爲如果追求高質量的開發仍是直接使用原生小程序更優吧~

相關文章
相關標籤/搜索