浅谈 Vue 2.x 生命周期和钩子函数

简介

每个 Vue 实例在被创建到销毁的过程中都会经历监听、编译模板、挂载、更新 DOM 等过程,也会运行一些相应的函数,这些函数被称作生命周期钩子函数,用户可以在这些钩子函数中做一些相应的处理,官方生命周期图如下:

从图中可以看出 Vue 生命周期函数有以下几个:

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestory
  • destoryed

钩子函数探究

将以下代码另存为 .html 在浏览器中打开

<!DOCTYPE html>
<html>
<head>
  <title>vue life cycle</title>
  <script type="text/javascript" src="https://cdn.bootcss.com/vue/2.5.21/vue.js"></script>
</head>
<body>
  <div id="app"><p>{{ mes + " " + text }}</p></div>

  <script type="text/javascript">
    var app = new Vue({
      el: '#app',
      data: { mes: "Hello" },
      computed: {
        text () { return "world" }
      },
      methods: {
        fun () {}
      },
      beforeCreate: function () {
        console.group('======= beforeCreate =======')
        console.log("el  : " + (this.$el ? this.$el.outerHTML : this.$el))
        console.log("data: " + JSON.stringify(this.$data))
        console.log("text: " + this.text)
        console.log("fun : " + this.fun)
        console.groupEnd()
      },
      created: function () {
        console.group('======= created =======')
        console.log("el  : " + (this.$el ? this.$el.outerHTML : this.$el))
        console.log("data: " + JSON.stringify(this.$data))
        console.log("text: " + this.text)
        console.log("fun : " + this.fun)
        console.groupEnd()
      },
      beforeMount: function () {
        console.group('======= beforeMount =======')
        console.log("el  : " + (this.$el ? this.$el.outerHTML : this.$el))
        console.log("data: " + JSON.stringify(this.$data))
        console.log("text: " + this.text)
        console.log("fun : " + this.fun)
        console.groupEnd()
      },
      mounted: function () {
        console.group('======= mounted =======')
        console.log("el  : " + (this.$el ? this.$el.outerHTML : this.$el))
        console.log("data: " + JSON.stringify(this.$data))
        console.log("text: " + this.text)
        console.log("fun : " + this.fun)
        console.groupEnd()
      },
      beforeUpdate: function () {
        console.group('======= beforeUpdate =======')
        console.log("el  : " + (this.$el ? this.$el.outerHTML : this.$el))
        console.log("data: " + JSON.stringify(this.$data))
        console.log("text: " + this.text)
        console.log("fun : " + this.fun)
        console.groupEnd()
      },
      updated: function () {
        console.group('======= updated =======')
        console.log("el  : " + (this.$el ? this.$el.outerHTML : this.$el))
        console.log("data: " + JSON.stringify(this.$data))
        console.log("text: " + this.text)
        console.log("fun : " + this.fun)
        console.groupEnd()
      },
      beforeDestroy: function () {
        console.group('======= beforeDestroy =======')
        console.log("el  : " + (this.$el ? this.$el.outerHTML : this.$el))
        console.log("data: " + JSON.stringify(this.$data))
        console.log("text: " + this.text)
        console.log("fun : " + this.fun)
        console.groupEnd()
      },
      destroyed: function () {
        console.group('======= destroyed =======')
        console.log("el  : " + (this.$el ? this.$el.outerHTML : this.$el))
        console.log("data: " + JSON.stringify(this.$data))
        console.log("text: " + this.text)
        console.log("fun : " + this.fun)
        console.groupEnd()
      }
    })
  </script>
</body>
</html>

在控制台中的打印结果如下:

======= beforeCreate =======
el  : undefined
data: undefined
text: undefined
fun : undefined
======= created =======
el  : undefined
data: {"mes":"Hello"}
text: world
fun : function () { [native code] }
======= beforeMount =======
el  : <div id="app"><p>{{ mes + " " + text }}</p></div>
data: {"mes":"Hello"}
text: world
fun : function () { [native code] }
======= mounted =======
el  : <div id="app"><p>Hello world</p></div>
data: {"mes":"Hello"}
text: world
fun : function () { [native code] }

从打印结果可以看出:

  • beforeCreate 阶段实例(app 变量)刚被创建, el、data、methods、computed 等 属性都未初始化
  • created 阶段 data、methods、computed 等属性已绑定到实例,但 el 属性尚未绑定
  • beforeMount 阶段 el 属性已经绑定到实例,但是模板尚未编译
  • mounted 阶段模板编译挂载完成

接下来在控制台中输入 app.mes = "Hi",打印出以下内容:

======= beforeUpdate =======
el  : <div id="app"><p>Hello world</p></div>
data: {"mes":"Hi"}
text: world
fun : function () { [native code] }
======= updated =======
el  : <div id="app"><p>Hi world</p></div>
data: {"mes":"Hi"}
text: world
fun : function () { [native code] }

从打印结果可以看出:

  • beforeUpdate 阶段 data 属性已更新,但是 el 尚未更新
  • updated 阶段 el 更新成功

继续在控制台中输入 app.$destroy(),又打印出以下内容:

======= beforeUpdate =======
el  : <div id="app"><p>Hi world</p></div>
data: {"mes":"Hi"}
text: world
fun : function () { [native code] }
======= updated =======
el  : <div id="app"><p>Hi world</p></div>
data: {"mes":"Hi"}
text: world
fun : function () { [native code] }

从打印结果可以发现,组件销毁后,实例依然存在,但是此时实例所有东西都会解绑定,所有的事件监听器会被移除,因此再次执行 app.message = "good morning!" 钩子函数将不再执行,DOM 也不再更新

除特殊说明外本人博客均属原创,转载请注明出处:http://blog.johnhan.cn/blog_1034.html
鄂ICP备17018604号-1  鄂公网安备42060702000030号