完全搞定vue2.0生命周期钩子函数问题

先给一张vue官网介绍生命周期的流程图


lifecycle


官方给的东西确定很官方啦,不过单看一张图对理解vue生命周期钩子函数来讲确定仍是有些难度的。不过各位小伙伴不要着急,本文 以简单直接的实例 来对此图进行理解。html


花10分钟读下去,相信我你必定会有一些收获(仅仅指刚入门的小伙伴,做者也是一名刚入门的前端小白,大佬请见谅哈。😁😁)

Vue2.0的生命周期钩子一共有10个分别简单介绍以下:

  • beforeCreate:在实例初始化以后,数据观测(data observer) 和 event/watcher 事件配置以前被调用。
  • created:实例已经建立完成以后被调用。在这一步,实例已完成如下的配置:数据监视(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
  • beforeMount:在挂载开始以前被调用相关的 render 函数首次被调用。
  • mounted:el 被新建立的 vm.el 替换,并挂载到实例上去以后调用此钩子函数,若是 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.el 也在文档内。
  • beforeUpdate:数据更新时调用,发生在虚拟 DOM 从新渲染和打补丁以前。你能够在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
  • updated:因为数据更改致使的虚拟 DOM 从新渲染和打补丁,在这以后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,因此你如今能够执行依赖于 DOM 的操做。
  • activated:keep-alive 组件激活时调用。
  • deactivated:keep-alive 组件停用时调用。
  • beforeDestroy:实例销毁以前调用。在这一步,实例仍然彻底可用。
  • destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的全部东西都会解绑定,全部的事件监听器会被移除,全部的子实例也会被销毁。

来吧 上代码!代码直接能够直接运行哦。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Vue-LifeClyle</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app" class="jing">
        <p>{{message}}</p>
        <keep-alive>
            <jh-component msg="2017年6月9日" v-if="show"></jh-component>
        </keep-alive>
    </div>
</body>
<script>
    var haohao = {
        template: '<div>from haohao: {{msg}}</div>',
        props: ['msg'],
        deactivated: function() {
            console.log('component deactivated!');
        },
        activated: function() {
            console.log('component activated');
        }
    };
    var app = new Vue({
        el: '#app',
        data: function() {
            return {
                message: 'jingjing',
                show: true //控制子组件是否显示
            };
        },
        beforeCreate: function() {
            console.group('beforeCreate Vue实例建立前的状态————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(state);
        },
        created: function() {
            console.group('created Vue实例建立完毕后状态————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(state);
        },
        beforeMount: function() {
            console.group('beforeMount 挂载前状态————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        mounted: function() {
            console.group('mounted 挂载后状态————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        beforeUpdate: function() {
            console.group('beforeUpdate 更新前状态————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
            console.log('beforeUpdate = ' + document.getElementsByTagName('p')[0].innerHTML);
        },
        updated: function() {
            console.group('updated 更新完成状态————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
            console.log('Updated = ' + document.getElementsByTagName('p')[0].innerHTML);
        },
        beforeDestroy: function() {
            console.group('beforeDestroy 销毁前状态————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        destroyed: function() {
            console.group('destroyed 销毁完成状态————————————————————');
            var state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            console.log(this.$el);
            console.log(state);
        },
        components: {
            'jh-component': haohao
        }
    });
</script>

<style>
    .jing {
        font-size: 50px;
        font-weight: bolder;
    }
</style>

</html>
复制代码

代码结构不难看懂

建立了一个 app 的Vue根实例,将其挂载到页面 id 为 app 的 Dom 元素上。 而后局部注册了一个组件名为 haohao 并在根实例中将其注册,使其能够在根实例的做用域中使用。 将子组件用 <keep-alive> 包裹,为接下来的测试做准备。前端

关于<keep-alive>的问题就不在这里做过多阐述了,你们能够参考如下两篇文章
    一、zhuanlan.zhihu.com/p/96740001
    二、www.jianshu.com/p/4b55d312d…vue

OK,到这里咱们就能够在谷歌浏览器中打开开发者工具,开始测试了!


一、beforeCreate 与 created

  • beforeCreate 执行时:datael均未初始化,值为undefined
  • created 执行时:Vue 实例观察的数据对象 data 已经配置好,已经能够获得app.message的值,但 Vue 实例使用的根 DOM 元素el还未初始化

二、beforeMount 与 mounted 和 activated 与 deactivated

  • beforeMount 执行时:datael均已经初始化,但从{{message}} 的展现状况能够看出此时 el 并无渲染数据,这里就是应用的 Virtual DOM(虚拟Dom)技术,先把坑占住了。到后面 mounted 挂载的时候再把值渲染上去npm

  • mounted 执行时:此时 el 已经渲染完成并挂载到实例上api

  • 咱们在控制台看到component activated被打印出来了,说明子组件jh-component<keep-alive> 包裹,随 el 的挂载而触发了。浏览器

  • 而后咱们进行一些操做,在控制台输入 app.show = false咱们再来看看有什么变化,测试结果以下图:bash

  • 怎么样,有没有发现什么?😉😉😉
  • 由于咱们在这里修改了data的值,因此会触发beforeUpdateupdated钩子函数,这里先无论这两个函数,咱们看到deactivated钩子已经触发,表示<keep-alive>已经停用。
    同时咱们的子组件也会消失。

三、beforeUpdate 和 updated

  • 咱们继续在控制台输入app.message = 'haohao'
  • 咱们发现beforeUpdateupdated触发时,el中的数据都已经渲染完成,但根据控制台打印的信息beforeUpdate = jingjingupdated = haohao可知,只有当updated钩子被调用时候,组件dom才会被更新。


四、beforeDestroy 与 destroyed

  • 在控制台输入app.$destroy()就能够将vue实例销毁,可是咱们发现销毁前和销毁后的实例dom结构没有任何改变,其实变化已经发生在了其余地方。
  • 做者查了一下官方文档描述:实例销毁后,Vue实例指示的全部东西都会解除绑定,全部的事件监听器会被移除,全部的子实例也会被销毁。

  • 咱们如今作最后一步操做就能证明上述结论。
  • 如今在控制台输入app.message = 'jingjing'发现结果以下图:

  • 咱们改变了data中的message属性,可是dom没有任何响应。说明Vue实例指示的全部东西都已经解除了绑定。终于写完了😄😄😄

写在最后


做者只是一名前端大白(●—●) 此篇文章是第一篇,若是文中有错误请各位大佬谅解一下,指出错误就更好了,让新人多一个学习的机会。😊😊app

此篇文章写的很浅显,若是有须要对内容有更深刻的学习,能够看看大佬OBKoro写的文章—— Vue的钩子函数[路由导航守卫、keep-alive、生命周期钩子]dom

但愿看完的朋友能够动动手点个赞再走哦,大家的支持是对我最大的鼓励啊!!!


参考文档

相关文章
相关标签/搜索