天天看點

小程式--mpvue開發的生命周期

mpvue 繼承自 Vue.js,其技術規範和文法特點與 Vue.js 保持一緻。

架構的原理

mpvue 保留了 vue.runtime 核心方法,無縫繼承了 Vue.js 的基礎能力

mpvue-template-compiler 提供了将 vue 的模闆文法轉換到小程式的 wxml 文法的能力

修改了 vue 的建構配置,使之建構出符合小程式項目結構的代碼格式: json/wxml/wxss/js 檔案

mpvue同時維護了Vue和小程式兩套機制

Vue執行個體生命周期

beforeCreate

created

beforeMount

mounted

beforeUpdate

updated

activated

deactivated

beforeDestroy

destroyed

微信小程式的生命周期鈎子

–app 部分–

onLaunch 初始化

onShow 當小程式啟動,或從背景進入前台顯示

onHide 當小程式從前台進入背景

–page 部分–

onLoad 監聽頁面加載

onShow 監聽頁面顯示

onReady 監聽頁面初次渲染完成

onHide 監聽頁面隐藏

onUnload 監聽頁面解除安裝

mpvue相容了上面Vue的生命周期和小程式的生命周期,并且mpvue會在小程式onReady後,再去觸發vue mounted生命周期。(官網聲明:除特殊情況外,不建議使用小程式的生命周期鈎子)

在mpvue中,vue和小程式生命周期鈎子的觸發順序是beforeCreate—created—onLaunch/onLoad—onShow—onReady—beforeMount—mounted—…

代碼驗證

app.vue

export default {
	......
    onLaunch() {
        console.log('onLaunch -- app');
    },
    onShow() {
        console.log('onShow -- app');
    },
    onHide() {
        console.log('onHide -- app');
    },
    ......
};
           

new page 頁面 index.vue

export default {
    components: {
        Card,
    },
    data() {
        return {};
    },
    beforeCreate() {
        console.log('beforeCreate --- new page');
    },
    created() {
        console.log('created --- new page');
    },
    onLoad() {
        console.log('onLoad --- new page');
    },
    onShow() {
        console.log('onShow --- new page');
    },
    onReady() {
        console.log('onReady --- new page');
    },
    beforeMount() {
        console.log('beforeMount --- new page');
    },
    mounted() {
        console.log('mounted --- new page');
    },
    beforeUpdate() {
        console.log('beforeUpdate --- new page');
    },
    updated() {
        console.log('updated --- new page');
    },
    beforeDestroy() {
        console.log('beforeDestroy --- new page');
    },
    destroyed() {
        console.log('destroyed --- new page');
    },
    onHide() {
        console.log('onHide --- new page');
    },
    onUnload() {
        console.log('onUnload --- new page');
    },
};
           

元件 card.vue

export default {
    data() {
        return {};
    },
    beforeCreate() {
        console.log('beforeCreate --- card component');
    },
    created() {
        console.log('created --- card component');
    },
    onLoad() {
        console.log('onLoad --- card component');
    },
    onReady() {
        console.log('onReady --- card component');
    },
    beforeMount() {
        console.log('beforeMount --- card component');
    },
    mounted() {
        console.log('mounted --- card component');
    },
    beforeUpdate() {
        console.log('beforeUpdate --- card component');
    },
    updated() {
        console.log('updated --- card component');
    },
    beforeDestroy() {
        console.log('beforeDestroy --- card component');
    },
    destroyed() {
        console.log('destroyed --- card component');
    },
    onUnload() {
        console.log('onUnload --- card component');
    },
};
           

App被建立,還未跳轉到new page頁面之前,觸發了app對象的onLaunch和onShow,并且new page頁面的beforeCreate和created也都在app建立之後就被觸發了

小程式--mpvue開發的生命周期

第一次跳轉到new page頁面:先觸發了小程式的生命周期再觸發beforeMount,并開始建立子元件card執行個體,按照beforeCreate–created–onLoad–onReady–beforeMount–mounted的順序觸發生命周期的鈎子

小程式--mpvue開發的生命周期

從new page頁面傳回入口app頁面:使用wx.navigateBack傳回上一頁時,小程式的生命周期鈎子onUnload被觸發。

但是vue的生命周期鈎子beforeDestroy和destroyed并沒有被觸發,也就是說小程式中new page的page對象被解除安裝了,但是new page和card執行個體并沒有被銷毀。

小程式--mpvue開發的生命周期

第二次跳轉到new page頁面:new page和card都已經被create且沒有destroy,當再次進入new page頁面時直接從onLoad–onShow–onReady開始觸發,mount和update過程也會觸發,而component之後update過程被觸發了。在onLoad之後經曆了幾個階段才開始觸發vue執行個體的生命周期鈎子,而上一次儲存在記憶體中的資料并沒有被destroy,是以在重新加載的過程中,vue執行個體還儲存着上一次加載頁面時的資料。

小程式--mpvue開發的生命周期

old問題:

遇到的問題主要是由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之後才存在,這裡需要注意做一些判斷。

開發中新遇到的一些問題:

關于onUnload:在開發表單之類的頁面的時候 希望每次打開這個頁面的時候表單内容都為空,除了上面提到的在onLoad中重置資料,在onUnload中重置也是可以的吧。。比如 頁面中有一個setTimeout發起的定時任務,那麼在離開目前頁面的時候希望清除這個任務就必須要在onUnload中操作了。。

參考網址

https://imweb.io/topic/5b8f42127cd95ea863193599

http://mpvue.com/mpvue/#_5