Vue生命周期

311 阅读2分钟

参考自:segmentfault.com/a/119000001…

Vue的生命周期中有8个钩子函数,分别为

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestroy
  • destroyed
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>生命周期</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        <h1>{{message}}</h1>
    </div>
</body>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: 'Vue的生命周期',
        },
        beforeCreate: function() {
            console.group('------beforeCreate创建前状态-----');
            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);
        },
        created: function() {
          console.group('------Created创建完毕状态-----');
          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)
        },
        beforeMount: function() {
          console.group('------beforeMount挂载前状态-----');
          console.log("%c%s", "color:red", "el:"+this.$el);
          console.log(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(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(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(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(this.$el);
          console.log("%%c%s","color:red","data:"+this.$data);
          console.log("%c%s","color:red","message:"+this.message)
        },
        destroyed: function() {
          console.group('------destoryed销毁完成状态-----');
          console.log("%c%s", "color:red", "el:"+this.$el);
          console.log(this.$el);
          console.log("%%c%s","color:red","data:"+this.$data);
          console.log("%c%s","color:red","message:"+this.message)
        }
    })
</script>
</html>

浏览器控制台输出代码结果为:

从图中可以看书vue实例在创建过程中调用的beforedCreate,created,beforeMount,mounted四个周期钩子函数。

1.在beforeCreate和created钩子函数之间的生命周期

在这个生命周期之间,会进行事件的初始化,数据的观测,可以看到created时数据已经与data属性绑定了,此时没有el选项(放在data中的属性当值发生改变的同时,试图也会发生改变。)

2.created和beforeMount之间的生命周期

这里会首先判断对象是否有el选项,如果有就继续向下编译,如果没有就停止编译,直到在该实例上调用vm.$mount(el)

如果没有el选项,则:

可以看到没有beforeCreate和created。

    var vm = new Vue({
        <!-- el: '#app', -->
        data: {
            message: 'Vue的生命周期',
        },
    ...
        }
    }).$mount("#app")

只要在后面调用vm.$mount(el)就可以执行beforeCreatecreated

如果没有template选项,会将外部HTML作为模板编译,如果有,则会将vue实例作为模板编译成render函数。也就是说template的优先级高于外部的HTML。

<body>
    <div id="app">
        <h1>{{message + "outer HTML"}}</h1>
    </div>
</body>
<script>
  var vm = new Vue({
    el: "#app",
    template: "<h1>{{message + 'inner template'}}</h1>",
    data: {
      message: 'vue生命周期'
    }
  })
</script>

页面会显示:

如果没有实例中的template,那么会出现

所以判读el要在编译template之前,因为vue需要通过el找到对应的template。

当然,vue可以通过render函数来直接做渲染操作。

<script>
  var vm = new Vue({
    el: '#app',
    render: function(createElement) {
      return createElement('h1', 'this is createElement')
    }
  })
</script>

此时页面中显示:

。 所有优先级排名是:

render>template选项>outer HTML

3.beforeMount和mounted之间的生命周期

src引入的的方式中,beforeMount阶段可以打印出el,而在vue-cli生成的项目中,无法打印出el

这个阶段是给虚拟DOM添加$el成员。

4.mounted阶段

可以看出beforeMount阶段在h1中通过{{message}进行占位,而在mounted阶段看到h1中的message变成了Vue的生命周期。这是因为在beforeMount阶段data中的message数据还没挂载到真实DOM上,而是在虚拟DOM上。

5.beforeUpdate和updated之间的生命周期

当vue中data数据发生变化,会触发对应组件的重新渲染,调用beforeUpdateupdated钩子函数,在浏览器控制台中输入

vm.message='更新'

会触发组件更新

beforeUpdate阶段,仍然可以监听到data的变化但是view层并没有重新渲染,是修改data的最后机会。

updated是在view重新渲染之后被触发。

6.beforeDestroy和destroyed之间的生命周期

beforeDestroyed在vue实例销毁之前被调用,在这一步,实例依然可以用。

destroyed在vue实例销毁后调用。调用destroyed之后,vue实例指示的所有东西都会解绑,所有的监听器会被移除,所有的子实例也会被销毁。