天天看点

小程序--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