Vue生命周期详解

Vue生命周期

每个Vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是Vue生命周期。

Vue官网上对于生命周期的图片描述:
在这里插入图片描述
Vue2.0生命周期钩子函数:

(1)beforeCreate:在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。

(2)created:实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

(3)beforeMount:在挂载开始之前被调用:相关的 render 函数首次被调用。

(4)mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。

如果 root 实例挂载了一个文档内元素,当 mounted 被调用,vm.$el 也在文档内。

(5)beforeUpdate:数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。

(6)updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。

(7)activated:keep-alive 组件激活时调用。

(8)deactivated:keep-alive 组件停用时调用。

(9)beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。

(10)destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

下面通过一个例子来理解vue的生命周期:创建一个Vue实例,将其挂载到页面id为app的dom元素上。

局部注册一个child并在根实例的作用域中将其注册使其可以在根实例的作用域中使用。

<div id="app">
    <p>{{message}}</p>
    <keep-alive>
        <my-components msg='hello' v-if="show"></my-components>
    </keep-alive>
</div>

补充:keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

在Vue项目中,难免会有列表页面或搜索结果列表页面,点击某个结构后,返回回来时,如果不对页面进行缓存,那么返回列表页面的时候会回到初始状态。如果想要返回页面时这个页面还是之前搜索结果的列表,这时就需要用到vue的keep-alive技术了。

var child={
    template:'<div>from child:{msg}</div>',
    props:['msg'],
    data:function(){
        return {
            childMsg:'child'
        };
    },
    deactivated:function(){
        console.log('component deactivated!');
    },
    activated:function(){
        console.log('component activated');
    }
};
var app=new Vue({
    el:'#app',
    data:function(){
        return {
            message:'father',
            show:true
        };
    },
    beforeCreate:function(){
        console.group('beforeCreate ------创建前状态')
        var state={
            'el':this.$el,
            'data':this.$data,
            'message':this.message
        }
        console.log(state)
    },
    created:function(){
        console.group('created ------------创建完毕状态')
        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:{
        'my-components':child
    }
})

(1)create和mounted相关
在这里插入图片描述

  • beforecreated:el 和 data 并未初始化 ;
  • created:完成了 data 数据的初始化,el没有;
  • beforeMount:完成了 el 和 data 初始化 ;
  • mounted :完成挂载。(注意:在beforeMount阶段应用的 Virtual DOM(虚拟Dom)技术,先把坑占住了,到后面mounted挂载的时候再把值渲染进去。)

(2)activated和destroyed相关

我们发现了activated周期钩子已经被触发,这是因为子组件my-components被 包裹,随el的挂载触发。

控制台输入 app.show = false:
在这里插入图片描述

由于我们修改了data的值,所以会触发beforeUpdate和updated钩子,而deactivated钩子已经触发,表示 <keep-alive>已经停用,符合预期结果。

现在我们对Vue实例进行销毁,调用app.$destroy()方法即可将其销毁。
在这里插入图片描述
如果使用app.message='message’更改data的message属性,发现dom没有进行响应(vue实例已经销毁)。

(3)updated相关
在这里插入图片描述
当beforeUpdate和updated触发时,el中的数据都已经渲染完成,但根据beforeUpdate == father而updated == message可知,只有updated钩子被调用时候,组件dom才被更新

也就是说,在beforeUpdate可以监听到data的变化,但是view层没有被重新渲染,view层的数据没有变化。等到updated的时候,view层才被重新渲染,数据更新。

总结:

  • 在created中可以对data数据进行操作,可以进行ajax请求将返回的数据赋给data
  • 在mounted钩子中对挂载的dom进行操作
  • 在使用vue-router时有时需要使用keep-alive来缓存组件状态,这个时候created钩子就不会被重复调用了,如果我们的子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值