Vue核心知識-Vue的生命周期方法

有哪些生命周期方法

把所有生命周期打印一遍

import Vue from 'vue'

const app = new Vue({
  // el: '#root',
  template: '<div>{{text}}</div>',
  data: {
    text: 0
  },
  beforeCreate () {
    console.log(this, 'breforeCreate')
  },
  created () {
    console.log(this, 'created')
  },
  beforeMount () {
    console.log(this, 'beforeMount')
  },
  mounted () {
    console.log(this, 'mounted')
  },
  beforeUpdate () {
    console.log(this, 'beforeUpdate')
  },
  updated () {
    console.log(this, 'updated')
  },
  activated () {
    console.log(this, 'activated')
  },
  deactivated () {
    console.log(this, 'deactivated')
  },
  beforeDestroy () {
    console.log(this, 'beforeDestroy')
  },
  destroyed () {
    console.log(this, 'destroyed')
  }
})

app.$mount('#root')

顯示結(jié)果

結(jié)果依次顯示 “breforeCreate” "created" "beforeMount" "mounted",說明在new Vue()時,這四個方法執(zhí)行了。

breforeMount 和 mounted

如果把el:'#root'注釋掉,就只顯示“breforeCreate” "created" ,因為mount的作用就是把vue組件生成的html內(nèi)容,掛載到html節(jié)點上,所以當(dāng)我們沒有指定el:'#root'或通過$mount進(jìn)行,是不會掛載到html節(jié)點上的。

breforeCreate 和 created

而 breforeCreate created 在初始化階段就執(zhí)行了。

beforeUpdate 和 updated

數(shù)據(jù)更新時,才會執(zhí)行。

例如,每一秒鐘更改數(shù)據(jù),相應(yīng)的每秒都會執(zhí)行這兩個生命周期

setInterval(() => {
  app.text = app.text += 1
}, 1000)

beforeDestroy 和 destroyed

vue實例銷毀時執(zhí)行。

例如,設(shè)置一秒鐘后銷毀,控制臺就會顯示 "beforeDestroy" 和 "destroyed"

setTimeout(() => {
  app.$destroy()
}, 1000)

activated 和 deactivated

和vue中一個原生的組件 keep-alive有關(guān)系。

分別打印出不同周期對應(yīng)的$el

beforeCreate () {
    console.log(this.$el, 'breforeCreate')
  },
  created () {
    console.log(this.$el, 'created')
  },
  beforeMount () {
    console.log(this.$el, 'beforeMount')
  },
  mounted () {
    console.log(this.$el, 'mounted')
  },

顯示結(jié)果

undefined "beforeCreate"
undefined "created"
<div id="root"></div> "beforeMount"
<div>0</div> "mounted"

可以看到

beforeCreate 和 created 的 $el 是undefined,所以 beforeCreate 和 created 階段是不能進(jìn)行dom操作的,因為拿不到 dom 節(jié)點。

brforeMount 時,$el變成了我們寫在 html 中 div 節(jié)點。

mounted 時, $el變成了 template 中的html,說明覆蓋了html原來的 div 節(jié)點。

mounted之后,我們調(diào)用的所有生命周期方法,拿到的節(jié)點,都是渲染之后的節(jié)點。

所以一般

  • 做 dom 相關(guān)操作會在 mounted 階段
  • 數(shù)據(jù)相關(guān)操作,可以在 created 或 mounted 階段

生命周期的調(diào)用順序

beforeCreate created beforeMount mounted 都是一次性的,組件只會調(diào)用一次。

beforeMount mounted 在服務(wù)端渲染,是不會被調(diào)用的,服務(wù)端渲染過程中,只會調(diào)用 beforeCreate created,因為 mount 是和 dom 操作相關(guān)的,服務(wù)端根本沒有 dom 執(zhí)行的環(huán)境, 所以不會有。

當(dāng)數(shù)據(jù)發(fā)生變化時,beforeUpdate 和 updated 會調(diào)用。

當(dāng)組件銷毀時,beforeDestroy 和 destroyed 會調(diào)用。

聲明周期中 VUE 實例有哪些區(qū)別

在不同的生命周期階段,this.$el是不同的,而在 mounted之后,一般不會改動 this.$el,而是圍繞階段做某些操作,要盡量避免 this.$el的變動,它會導(dǎo)致一些 vue 錯誤。

理解生命周期就是理解一張圖

Vue ??????????????¨???
  1. init,new Vue() 先執(zhí)行 init 操作,這個操作是默認(rèn)執(zhí)行的。
    1. init Events $ Lifecycle,調(diào)用 beforeCreate,所以此時,事件OK,但reactive不OK,所以這個階段不要修改數(shù)據(jù) data 中的數(shù)據(jù)。
    2. init injections $ reactivity,調(diào)用 created ,ajax請求獲取數(shù)據(jù)賦值,最早在 created 階段做。
  2. 判斷 Has "el" option
    1. 如果有,執(zhí)行下一步。
    2. 如果沒有,等我們調(diào)用 vm.$mounted(el)。
  3. 判斷 Has "template" options
    1. 如果有,把 template 解析生一個 render 函數(shù)。render 函數(shù)會用 template 中的 html 去覆蓋 html 中的 div 標(biāo)簽。在使用 .vue 文件進(jìn)行開發(fā)的過程中,是沒有 template 的,我們在 .vue 文件中寫的 template 都經(jīng)過了 vue-loader 處理,直接變成了 render 函數(shù),放在vue-loader 解析過的文件中;這樣做的好處,把 template 解析成 render 函數(shù),比較耗時,vue-loader 處理后,我們在頁面上執(zhí)行代碼時,效率會變高。
    2. 如果沒有,Compile el's outerHTML as template
  4. 有了 render 函數(shù)之后
    1. beforeMount 執(zhí)行
  5. 執(zhí)行 render 函數(shù)
    1. Create vm.$el and replace "el" with it
  6. 執(zhí)行 render 函數(shù)之后
    1. mounted 執(zhí)行
  7. mounted之后,實例創(chuàng)建完成,后續(xù)過程,都是通過外部觸發(fā)進(jìn)行的。
  8. 當(dāng)數(shù)據(jù)變化時
    1. beforeUpdate 執(zhí)行
    2. Virtual DOM re-render and patch
    3. updated 執(zhí)行
  9. 當(dāng)組件銷毀時
    1. beforeDestroy 執(zhí)行
    2. Teardown watchers,child comonents and event listeners
    3. destroyed 執(zhí)行

render 函數(shù)

直接使用 render 函數(shù)和使用 template 一樣的。

import Vue from 'vue'

const app = new Vue({
  // template: '<div>{{text}}</div>',
  data: {
    text: 0
  },
  render (h) {
    return h('div', {}, this.text) // 參數(shù)1,創(chuàng)建的標(biāo)簽;參數(shù)2,對象配置;參數(shù)3,標(biāo)簽內(nèi)容
  },
})

app.$mount('#root')

render 函數(shù)執(zhí)行時機(jī)

render (h) {
    console.log('render function invoked')
    return h('div', {}, this.text)
  },

控制臺結(jié)果

undefined "beforeCreate"
undefined "created"
<div id="root"></div> "beforeMount"
render function invoked
<div>0</div> "mounted"

在beforeMount 和 mounted 之間執(zhí)行的

renderError 方法

renderError 方法,只有在開發(fā)時,才會被調(diào)用,正式打包上線時,不會被調(diào)用。幫助我們調(diào)試 render 中的錯誤。renderError 方法,只有在本組件 render 出現(xiàn)錯誤時,才會被調(diào)用;如果是子組件報錯,是不會被捕獲到的。

當(dāng) render 函數(shù)報錯時,renderError 方法會執(zhí)行。

render (h) {
    throw new TypeError('render error')
    // console.log('render function invoked')
    // return h('div', {}, this.text)
  },
  renderError (h, err) {
    return h('div', {}, err.stack)
  }

errorCaptured 方法

可以用在正式開發(fā)環(huán)境中,幫助我們搜集線上的錯誤。如果在根組件使用這個方法,而根組件的子組件報的任何錯誤都可捕捉到,除非子組件把向上冒泡停止掉。

errorCaptured 方法使用與 renderError 相似,唯一的區(qū)別是:errorCaptured 會向上冒泡,并且正式環(huán)境可以使用。

總結(jié)

生命周期的執(zhí)行順序,調(diào)用時機(jī),不同時機(jī)進(jìn)行哪些操作,不同生命周期this.$el的區(qū)別。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 涉及到鉤子函數(shù)有:1)beforeCreate;2)created;3)beforeMount;4)mounted...
    puxiaotaoc閱讀 12,887評論 1 10
  • vue生命周期總共分為8個階段創(chuàng)建前/后,載入前/后,更新前/后,銷毀前/后。 創(chuàng)建前/后: 在beforeCre...
    雨蒙_snow閱讀 1,385評論 0 1
  • 首先,每個Vue實例在被創(chuàng)建之前都要經(jīng)過一系列的初始化過程,這個過程就是vue的生命周期。首先看一張圖吧~這是官方...
    廊橋夢醉閱讀 2,811評論 0 49
  • 兒童食療止咳化痰,一定要對癥下食! 簡單辨別咳嗽類型,進(jìn)而對癥制作飲食。 首先我們學(xué)習(xí)下最簡單的辨別風(fēng)熱型咳嗽和風(fēng)...
    聽雨心依閱讀 421評論 0 0
  • 金風(fēng)未濃清涼早,農(nóng)家禾穗秋漿少。已見黃花催葉老,稀飛鳥。心憂春夢隨煙了。 誰為兆民除重惱,伸來玉手招招巧。取道長河...
    宏波_閱讀 550評論 0 4

友情鏈接更多精彩內(nèi)容