Vue的生命週期

爲何要認識Vue的生命週期

Vue的生命週期是一個很是重要的點,若是不懂Vue的生命週期,那麼不少時候,就不知道Vue的實際渲染時機,程序中會出現各類bug。javascript

所以,學習Vue的生命週期是很是用必要的。css

Vue2的生命週期

簡單認識生命週期

前期準備

下面咱們來畫一個簡單的生命週期圖:html

new Vue()
                 ||
                 ||
                 ||
          初始化event和watch
                 ||
                 ||=====> beforeCreate
                 ||
       屬性、方法、數據等內容的計算
                 ||
                 ||=====> created
                 ||
              存在el選項
                 ||
                 ||
                 ||
          不存在template選項
                 ||
                 ||=====> beforeMount
                 ||
         建立vm.$el替換el選項
                 ||
                 ||=====> mounted
                 ||
            當內容發生更新
                 ||
                 ||=====> beforeUpdate
                 ||
           虛擬DOM從新渲染
                 ||
                 ||=====> updated
                 ||
         調用vm.$destroy()
                 ||
                 ||=====> beforeDestroy
                 ||
     卸載watcher、子組件和事件監聽=====> destroyed

生命週期圖完成以後,根據這張圖來寫對應的代碼:vue

<!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>

從頭至尾看生命週期

運行上面的程序,會在控制檯中看到前四個生命週期鉤子:java

1.beforeCreateweb

在這個階段,Vue實例中的事件監聽和watch都已經初始化完成了。若是在Vue實例中寫一個watch,就能夠清晰的看出來了。segmentfault

clipboard.png

2.createdapp

在這個階段,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

參考連接

相關文章
相關標籤/搜索