4

为什么要认识Vue的生命周期

Vue的生命周期是一个非常重要的点,如果不懂Vue的生命周期,那么很多时候,就不知道Vue的实际渲染时机,程序中会出现各种bug。

因此,学习Vue的生命周期是非常用必要的。

Vue2的生命周期

简单认识生命周期

前期准备

下面我们来画一个简单的生命周期图:

              new Vue()
                 ||
                 ||
                 ||
          初始化event和watch
                 ||
                 ||=====> beforeCreate
                 ||
       属性、方法、数据等内容的计算
                 ||
                 ||=====> created
                 ||
              存在el选项
                 ||
                 ||
                 ||
          不存在template选项
                 ||
                 ||=====> beforeMount
                 ||
         创建vm.$el替换el选项
                 ||
                 ||=====> mounted
                 ||
            当内容发生更新
                 ||
                 ||=====> beforeUpdate
                 ||
           虚拟DOM重新渲染
                 ||
                 ||=====> updated
                 ||
         调用vm.$destroy()
                 ||
                 ||=====> beforeDestroy
                 ||
     卸载watcher、子组件和事件监听=====> destroyed

生命周期图完成之后,根据这张图来写对应的代码:

<!DOCTYPE html>
<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>vue生命周期学习</title>
  <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
</head>

<body>
  <div id="app">
    <h1>{{message}}</h1>
    <ul>
      <li v-for="item in arr">{{item}}</li>
    </ul>
  </div>
</body>
<script>
  var vm = new Vue({
    el: '#app', // 存在el选项,没有template选项
    data: {
      message: 'Vue的生命周期',
      arr: ['a', 'b', 'c']
    },
    beforeCreate: function () {
      console.group('<====== beforeCreate ======>')
      console.log("%c%s", "color:red", "el     : ", this.$el)
      console.log("%c%s", "color:red", "data   : ", this.$data)
      console.groupEnd('<====== beforeCreate ======>')
    },
    created: function () {
      console.group('<====== created ======>')
      console.log("%c%s", "color:red", "el     : ", this.$el)
      console.log("%c%s", "color:red", "data   : ", this.$data)
      console.groupEnd('<====== created ======>')
    },
    beforeMount: function () {
      console.group('<====== beforeMount ======>')
      console.log("%c%s", "color:red", "el     : ", this.$el)
      console.log("%c%s", "color:red", "data   : ", this.$data)
      console.groupEnd('<====== beforeMount ======>')
    },
    mounted: function () {
      console.group('<====== mounted ======>')
      console.log("%c%s", "color:red", "el     : ", this.$el)
      console.log("%c%s", "color:red", "data   : ", this.$data)
      console.groupEnd('<====== mounted ======>')
    },
    beforeUpdate: function () {
      console.group('<====== beforeUpdate ======>')
      console.log("%c%s", "color:red", "el     : ", this.$el)
      console.log("%c%s", "color:red", "data   : ", this.$data)
      console.groupEnd('<====== beforeUpdate ======>')
    },
    updated: function () {
      console.group('<====== updated ======>')
      console.log("%c%s", "color:red", "el     : ", this.$el)
      console.log("%c%s", "color:red", "data   : ", this.$data)
      console.groupEnd('<====== updated ======>')
    },
    beforeDestroy: function () {
      console.group('<====== beforeDestroy ======>')
      console.log("%c%s", "color:red", "el     : ", this.$el)
      console.log("%c%s", "color:red", "data   : ", this.$data)
      console.groupEnd('<====== beforeDestroy ======>')
    },
    destroyed: function () {
      console.group('<====== destroyed ======>')
      console.log("%c%s", "color:red", "el     : ", this.$el)
      console.log("%c%s", "color:red", "data   : ", this.$data)
      console.groupEnd('<====== destroyed ======>')
    }
  })
</script>

</html>

从头到尾看生命周期

运行上面的程序,会在控制台中看到前四个生命周期钩子:

1.beforeCreate

在这个阶段,Vue实例中的事件监听和watch都已经初始化完成了。如果在Vue实例中写一个watch,就可以清晰的看出来了。

clipboard.png

2.created

在这个阶段,Vue实例中的data、methods等内容都已经初始化完成了。

clipboard.png

3.beforeMount

这个阶段会进行模板的渲染,把HTML结构渲染出来,但是Vue实例中的数据没有渲染到DOM中。

clipboard.png

4.mounted

在这个阶段,el被新创建的vm.$el替换,并挂在到实例上去之后调用该钩子函数。这个时候,Vue实例中的data会被渲染到DOM中。

clipboard.png

5.beforeUpdate和updated

下面,手动更新数据,来调用其他的钩子函数。

// 在控制台宏输入
vm.message='123'

在这个阶段,会更新数据,并重新渲染DOM和虚拟DOM。

clipboard.png

6.beforeDestroy和destroyed

下面手动调用:

// 在控制台中输入
vm.$destroy()

在这个阶段会销毁Vue实例,生命周期结束。

clipboard.png

Vue实例中的template

clipboard.png

Vue实例中不存在template

如果Vue中不存在template选项,那么会把外部的HTML作为template进行渲染。

<body>
  <div id="app">
    <h1>外部HTML : {{message}}</h1>
  </div>
</body>
<script>
  var vm = new Vue({
    el: '#app',
    data: {
      message: 'this is a message'
    }
  })
</script>

显示的效果:

clipboard.png

Vue实例中存在template

如果Vue实例中存在template,那么就会优先使用Vue实例中的template作为模板进行渲染。

<body>
  <div id="app">
    <h1>外部HTML : {{message}}</h1>
  </div>
</body>
<script>
  var vm = new Vue({
    el: '#app',
    template: "<h1>Vue实例中的template : {{message}}</h1>",
    data: {
      message: 'this is a message'
    }
  })
</script>

显示的效果:

clipboard.png

Vue实例中存在render函数

但是render函数更接近底层渲染机制,因此,存在render函数的话,render函数的优先级最高。

<body>
  <div id="app">
    <h1>外部HTML : {{message}}</h1>
  </div>
</body>
<script>
  var vm = new Vue({
    el: '#app',
    template: "<h1>Vue实例中的template : {{message}}</h1>",
    data: {
      message: 'this is a message'
    },
    render: function (createElement) {
      return createElement('h1', 'render函数 : ' + this.message)
    }
  })
</script>

显示的效果:

clipboard.png

参考链接


沫俱宏
763 声望33 粉丝

自己的肯定最重要,做任何决定,一定要从内心出发