Vue组件的生命周期

导读:本篇文章讲解 Vue组件的生命周期,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、生命周期 & 生命周期函数

       1. 生命周期Life Cycle)是指一个组件从创建 -> 运行 -> 销毁的整个阶段,强调的是一个时间段

       2. 生命周期函数:是由 vue 框架提供的内置函数,会伴随着组件的生命周期,自动按次序执行,不需要用户显式地调用 —— 钩子函数

       注意: 生命周期强调的是时间段,生命周期函数强调的是时间点。

二、组件生命周期函数的分类

Vue组件的生命周期

三、生命周期图示

Vue组件的生命周期

 四、Vue2.0的生命周期函数

       组件的生命周期经历的阶段:

       1. 创建阶段:beforeCreate、created、beforeMount、mounted

       2. 运行阶段:beforeUpdate、updated

       3. 销毁阶段:beforeDestroydestroyed

       1. 创建阶段

     (1)beforeCreate

       创建阶段的第1个生命周期函数,组件的props,methods,data尚未被创建,处于不可用。

       在组件创建之前运行,此时Vue实例的el、data、data中的变量均为undefined

     (2)created(最早可以发起Ajax请求

       创建阶段的第2个生命周期函数,组件的props,methods,data已创建好,可以使用,但组件的模板结构尚未生成 ,不能操作DOM,但最早可以发起Ajax请求

       组件已经创建完成,data、props已经初始化了,el还是undefined(组件还没有挂载到DOM上)

       经常通过created函数调用methods中的方法,请求服务器的数据,并且把请求到的数据转存到data中,供template模板渲染时去使用

      (3)beforeMount

       创建阶段的第3个生命周期函数,内存编译好的HTML结构准备渲染到浏览器中,此时浏览器中还没有当前组件的DOM结构,无法操作DOM

       el被绑定(和DOM绑定),但未挂载

     (4)mounted(最早可以操作DOM)

       创建阶段的第4个生命周期函数,已经渲染内存的HTML结构到浏览器中,包含了当前组件的DOM结构,最早可以操作DOM

       组件挂载之后,el绑定、组件挂载

       2. 运行阶段(根据数据变化进入运行阶段)

       (1) beforeUpdate

       运行阶段的第1个生命周期函数,将要根据数据变化后、最新的数据,重新渲染组件的模板结构,此时数据变化后还未放到模板结构上

       当组件的内容被改变、隐藏的组件被显示、显示的组件被隐藏等触发

       (2)updated(当数据变化后,为了能够操作到最新的DOM结构)

       运行阶段的第2个生命周期函数,完成了最新数据重新渲染到组件的DOM结构

       当数据变化后,为了能够操作到最新的DOM结构,应将代码写在update中

       更新结束后触发

       3. 销毁阶段

       (1)beforeDestroy

       销毁阶段的第1个生命周期函数,组件还处于正常工作状态。

       在组件销毁之前。组件还是正常使用

     (2) destroyed

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

       组件销毁之后

​       4. keep-alive组件:是vue的内置组件,用来保持vue组件运行的某种状态,避免被重新渲染

        强调:组件(页面的组成部件)

​        第一步:创建组件(定义组件),组件文件的扩展名(后缀)可以是.vue,也可以是.js

        第二步:在使用组件的位置导入,注册组件

       ​ 第三步:使用组件:像html标签一样使用

五、示例

       我们创建了一个Vue根实例命名为app,将其挂载到页面id为app的dom元素上。

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

       将子组件用<keep-alive> 包裹,为接下来的测试作准备。

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

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

    <script src="./js/vue.js"></script>

<body>
    <div id="app">
        <p>{{ message }}</p>
        <keep-alive>
            <my-components msg="hello" v-if="show"></my-components><!-- 子组件 -->
         </keep-alive>
    </div>

    <script>
        //1.定义子组件
        var child = {
            template:'<div>from child: {{msg}}</div>',//子组件的html模板内容
            props:['msg'],//接收父组件传递的msg
            data:function(){
                return {
                    childMsg:'child'
                }
            },
            deactivated:function(){//钩子函数:在组件非运行时触发
                console.log('component deactivated!');
            },
            activated:function(){//钩子函数:在组件运行时触发
                console.log('component activated!');
            }
        }

        //2.创建Vue实例:和DOM中的id为app的元素绑定
        const vm = new Vue({
            el:'#app',
            components:{//注册子组件
                'my-components':child
            },
            data(){
                return {
                    message:'father',
                    show:true
                }
            },
            // 3.定义生命周期函数
            beforeCreate:function(){
                console.group('beforeCreate 组件创建之前的状态---------------')
                let state = {
                    'el':this.$el,
                    'data':this.$data,
                    'message':this.message
                }
                console.log(state);
            },
            created:function(){
                console.group('created 组件创建完成的状态---------------');
                let state = {
                    'el':this.$el,
                    'data':this.$data,
                    'message':this.message
                }
                console.log(state); 
            },
            beforeMount:function(){
                console.group('beforeMount 组件挂载前的状态---------------');
                let state = {
                    'el':this.$el,
                    'data':this.$data,
                    'message':this.message
                }
                console.log(this.$el);
                console.log(state); 
            },
            mounted:function(){
                console.group('mounted 组件挂载结束的状态---------------');
                let state = {
                    'el':this.$el,
                    'data':this.$data,
                    'message':this.message
                }
                console.log(this.$el);
                console.log(state); 
            },
            beforeUpdate:function(){
                console.group('beforeUpdate 更新前的状态---------------');
                let 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 更新完成的状态---------------');
                let 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 组件销毁前的状态---------------');
                let state = {
                    'el':this.$el,
                    'data':this.$data,
                    'message':this.message
                }
                console.log(this.$el);
                console.log(state); 
            },
            destroyed:function(){
                console.group('destroyed 组件销毁完成的状态---------------');
                let state = {
                    'el':this.$el,
                    'data':this.$data,
                    'message':this.message
                }
                console.log(this.$el);
                console.log(state); 
            }
        })
    </script>
</body>

       1. create 和 mounted 相关

Vue组件的生命周期

       beforecreate:el 和 data 并未初始化 ;

       created:完成了 data 数据的初始化,el没有;

       beforeMount:完成了 el 和 data 初始化 ;

       mounted :完成挂载。(注意:在beforeMount阶段应用的 Virtual DOM(虚拟Dom)技术,先把坑占住了,到后面mounted挂载的时候再把值渲染进去。)

       2. activated 和 destroyed相关

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

       现在我们将此组件停用进行测试:由于子组件具有一个v-if指令v-if=”show”,因此我们可以通过将show的值置为false将其销毁。控制台输入 对象名.show = false;测试结果如下:

Vue组件的生命周期

       由于在这里我们修改了data的值,所以会触发beforeUpdate和updated钩子,这里先不讨论这一组钩子,我们看到deactivated钩子已经触发,表示<keep-alive>已经停用,符合预期结果。

       现在我们对Vue实例进行销毁,调用app.$destroy()方法即可将其销毁,控制台测试如下:

Vue组件的生命周期

       这里我们将data中的message属性改成了’message’,发现dom并没有进行相应的响应,这证实了之前的说法。同样,如果你在子组件也加入destroyed钩子,发现该钩子也会被触发,这也证明了子实例也会被一起销毁。这里的销毁并不指代’抹去’,而是表示’解绑’。

       3. updated相关

       beforeUpdate和updated是最后一对周期钩子了。

Vue组件的生命周期

       我们发现beforeUpdate和updated触发时,el中的数据都已经渲染完成,但根据beforeUpdate == father而updated == message可知,只有updated钩子被调用时候,组件dom才被更新。

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

六、使用建议

      1. 在created钩子中可以对data数据进行操作,这个时候可以进行ajax请求将返回的数据赋给data

      2. 在mounted钩子对挂载的dom进行操作

     3. 在使用vue-router时有时需要使用<keep-alive></keep-alive>来缓存组件状态,这个时候created钩子就不会被重复调用了,如果我们的子组件需要在每次加载的时候进行某些操作,可以使用activated钩子触发。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/79742.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!