美文网首页
Vue生命周期钩子函数

Vue生命周期钩子函数

作者: dingFY | 来源:发表于2020-09-07 09:40 被阅读0次

    生命周期钩子就好像是把人的出生到死亡分成一个个阶段,你肯定是在出生阶段起名字,而不会在成年或者死亡的阶段去起名字。组件也是一样, Vue 实例从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期,各个阶段有相对应的事件钩子,用户可以在特定的阶段调用特定的方法。每个阶段组件内部的属性都是不一样的,比如created钩子时视图还没有渲染,就不能做一些dom操作。所以一般特定的钩子做特定的事。

    一、Vue生命周期图

    二、Lifecycle hooks详解

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

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

    beforeMount:在挂载开始之前被调用:相关的 render 函数首次被调用。(该钩子在服务器端渲染期间不被调用)

    mounted:el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。

    beforeUpdate:数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。(该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。)

    updated:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。

    activated:keep-alive 组件激活时调用。(该钩子在服务器端渲染期间不被调用)

    deactivated: keep-alive 组件停用时调用。(该钩子在服务器端渲染期间不被调用)

    beforeDestory: 实例销毁之前调用。在这一步,实例仍然完全可用。(该钩子在服务器端渲染期间不被调用)

    destroyed: Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。(该钩子在服务器端渲染期间不被调用)

    三、注意

    所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos())。这是因为箭头函数绑定了父上下文,因此 this 与你期待的 Vue 实例不同,this.fetchTodos 的行为未定义。

    // good
    
    created: function() {} 
    
    created() {}
    
    // error
    
    created: () => {}
    

    四、生命周期执行顺序

    <!DOCTYPE html>
    <html>
    
    <head>
      <title>Vue生命周期</title>
      <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script>
    </head>
    
    <body>
      <div id="app">
        <p>{{ message }}</p>
      </div>
    
      <script type="text/javascript">
        var app = new Vue({
          el: '#app',
          data: {
            message: "Hello World"
          },
          beforeCreate: function () {
            console.group('beforeCreate 创建前状态===============》');
            console.log("%c%s", "color:red", "el     : " + this.$el);    //undefined
            console.log("%c%s", "color:red", "data   : " + this.$data);  //undefined 
            console.log("%c%s", "color:red", "message: " + this.message) //undefined 
          },
          created: function () {
            console.group('created 创建完毕状态===============》');
            console.log("%c%s", "color:red", "el     : " + this.$el);     //undefined
            console.log("%c%s", "color:red", "data   : " + this.$data);   //已被初始化 
            console.log("%c%s", "color:red", "message: " + this.message); //已被初始化
          },
          beforeMount: function () {
            console.group('beforeMount 挂载前状态===============》');
            console.log("%c%s", "color:red", "el     : " + (this.$el));   //已被初始化
            console.log("%c%s", "color:red", "data   : " + this.$data);   //已被初始化  
            console.log("%c%s", "color:red", "message: " + this.message); //已被初始化  
          },
          mounted: function () {
            console.group('mounted 挂载结束状态===============》');
            console.log("%c%s", "color:red", "el     : " + this.$el);     //已被初始化
            console.log("%c%s", "color:red", "data   : " + this.$data);   //已被初始化
            console.log("%c%s", "color:red", "message: " + this.message); //已被初始化 
          },
          beforeUpdate: function () {
            console.group('beforeUpdate 更新前状态===============》');
            console.log("%c%s", "color:red", "el     : " + this.$el);
            console.log("%c%s", "color:red", "data   : " + this.$data);
            console.log("%c%s", "color:red", "message: " + this.message);
          },
          updated: function () {
            console.group('updated 更新完成状态===============》');
            console.log("%c%s", "color:red", "el     : " + this.$el);
            console.log("%c%s", "color:red", "data   : " + this.$data);
            console.log("%c%s", "color:red", "message: " + this.message);
          },
          beforeDestroy: function () {
            console.group('beforeDestroy 销毁前状态===============》');
            console.log("%c%s", "color:red", "el     : " + this.$el);
            console.log("%c%s", "color:red", "data   : " + this.$data);
            console.log("%c%s", "color:red", "message: " + this.message);
          },
          destroyed: function () {
            console.group('destroyed 销毁完成状态===============》');
            console.log("%c%s", "color:red", "el     : " + this.$el);
            console.log("%c%s", "color:red", "data   : " + this.$data);
            console.log("%c%s", "color:red", "message: " + this.message)
          }
        })
      </script>
    </body>
    
    </html>
    

    按F12打开浏览器控制台,查看console结果

    由上图我们会发现没有执行beforeUpdate、updated、beforeDestory、destroyed这四个函数。

    1、beforeCreate 此时$el、data 的值都为undefined

    2、创建之后,此时可以拿到data的值,但是$el依旧为undefined

    3、mount之前,$el的值为“虚拟”的元素节点

    4、mount之后,mounted之前,“虚拟”的dom节点被真实的dom节点替换,并将其插入到dom树中,于是在触发mounted时,可以获取到$el为真实的dom元素()

    五、beforeUpdate | updated

    接着尝试在浏览器控制台改变data的数据值,输入以下命令

    app.message='Hello Demi'
    

    data里面的值被修改后,就会触发beforeUpdate和updated操作

    六、destroy | destroyed

    接着尝试在浏览器控制台输入以下命令

    app.$destroy()
    

    对vue实例进行销毁,销毁之后所有东西都会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

    七、使用场景

    • beforeCreate:举个栗子:可以在这加个loading事件
    • created:在这结束loading,还做一些初始化,实现函数自执行
    • mounted:在这发起后端请求,拿回数据,配合路由钩子做一些事情
    • beforeDestroyed:你确认删除XX吗?
    • destroyed :当前组件已被删除,清空相关内容

    八、参考链接

    http://www.cnblogs.com/gagag/p/6246493.html

    文章每周持续更新,可以微信搜索「 前端大集锦 」第一时间阅读,回复【视频】【书籍】领取200G视频资料和30本PDF书籍资料

    相关文章

      网友评论

          本文标题:Vue生命周期钩子函数

          本文链接:https://www.haomeiwen.com/subject/duaynhtx.html