vue生命周期詳解

1.vue基本生命周期

lifecycle.png

vue源碼中最終執行生命周期函數都是調用callHook方法,callHook函數的邏輯很簡單,根據傳入的生命周期類型 hook,去拿到 vm.$options[hook]對應的回調函數數組,然后遍歷執行,執行的時候把 vm作為函數執行的上下文。

1. new Vue(options):創建一個vm實例;

2. mergeOptions(resolveConstructorOptions(vm.constructor), options, vm):合并Vue構造函數里options和傳入的options或合并父子的options。比如:在mergeOptions函數中會調用mergeHook方法合并生命周期的鉤子函數,mergeHook方法原理是只有父時返回父,只有子時返回數組類型的子。父、子都存在時,將子添加在父的后面返回組合而成的數組。這也是父子均有鉤子函數的時候,先執行父的后執行子的的原因;

3. initLifecycle(vm)、initEvents(vm)、initRender(vm):在創建的vm實例上初始化生命周期、事件、渲染相關的屬性;

4. callHook(vm, 'beforeCreate'):調用beforeCreate生命周期鉤子函數;

5. initInjections(vm)、initState(vm)、initProvide(vm):初始化數據:inject、state、provide。initState 的作用是初始化 props、data、methods、watch、computed 等屬性;

6. callHook(vm, 'created'):調用created生命周期鉤子函數;

7. vm.$mount(vm.$options.el)$mount方法在多個文件中都有定義,如"src/platform/web/entry-runtime-with-compiler.js"、"src/platform/web/runtime/index.js"、"src/platform/weex/runtime/index.js"。因為$mount方法的實現是和平臺、構建方式相關的。以"entry-runtime-with-compiler.js"為例,關鍵步驟是查看vm.$options中是否有render方法,如果沒有則會根據el和template屬性確定最終的template字符串,再調用compileToFunctions方法將template字符串轉為render方法,最后,調用原先原型上的$mount方法,即開始執行"lifecycle.js"中mountComponent方法;

8. callHook(vm, 'beforeMount'):調用beforeMount生命周期鉤子函數;

9. vm._render() => vm._update() => vm.__patch__():先執行vm._render方法,即調用createElement生成虛擬DOM,即VNode ,每個VNode有children ,children 每個元素也是?個 VNode,這樣就形成了?個 VNode Tree;再調用vm._update方法進行首次渲染,vm._update方法核心是調用vm.patch方法,這個方法跟vm.$mount一樣跟平臺相關;vm.patch方法則是根據生成的VNode Tree遞歸createElm方法創建真實Dom Tree掛載到Dom上;

10. callHook(vm, 'mount'):調用mount生命周期鉤子函數:VNode patch 到 Dom 之后會執行 'invokeInsertHook'函數,把insertedVnodeQueue中保存的mount鉤子函數執行一遍,insertedVnodeQueue隊列中的鉤子函數是在根據VNode Tree遞歸createElm方法創建真實Dom Tree過程生成的鉤子函數順序隊列,因此mounted鉤子函數的執行順序是先子后父;

11. data changes:數據更新,nextTick中執行flushSchedulerQueue方法,該方法會執行watcher隊列中的watcher;

12. callHook(vm, 'beforeUpdate'):執行watcher時會執行watcher的before方法,即調用beforeUpdate生命周期鉤子函數;

13. Virtual DOM re-render and patch:重新render生成新的Virtual DOM,并且patch到DOM上;

14. callHook(vm, 'updated'):調用updated生命周期鉤子函數;

15. vm.$destroy():啟動卸銷毀過程;

16. callHook(vm, 'beforeDestroy'):調用beforeDestroy生命周期鉤子函數;

17. Teardown watchers, childcomponents and event listeners:執行一系列銷毀動作,在 $destroy 的執行過程中,它又會執行vm.__patch__(vm._vnode, null) 觸發它子組件的銷毀鉤子函數,這樣一層層的遞歸調用,所以 destroyed 鉤子函數執行順序是先子后父,和 mounted 過程一樣。

18. callHook(vm, 'destroyed '):調用destroyed 生命周期鉤子函數。

2. errorCaptured生命周期鉤子函數

  • 當捕獲一個來自子孫組件的錯誤時被調用。此鉤子會收到三個參數:錯誤對象、發生錯誤的組件實例以及一個包含錯誤來源信息的字符串。此鉤子可以返回 false 以阻止該錯誤繼續向上傳播。

  • 如果一個組件的繼承或父級從屬鏈路中存在多個 errorCaptured 鉤子,則它們將會被相同的錯誤逐個喚起。

  • 默認情況下,如果全局的 config.errorHandler 被定義,所有的錯誤仍會發送它,因此這些錯誤仍然會向單一的分析服務的地方進行匯報。

3. keep-alive組件

  • keep-alive組件是vue的內置抽象(abstract)組件,抽象組件在initLifecycle過程中 組件實例建立父子關系時會被忽略,因此他自身不會渲染一個DOM元素,也不會出現在父組件鏈中。

  • keep-alive作用是用于包裹動態組件,緩存不活動的組件實例。keep-alive自定義實現了render函數并利用了插槽slot,render函數中先獲取它的默認插槽,再獲取到它的第一個組件子節點,因此keep-alive組件只處理第一個子元素,所以一般和它搭配使用的有component動態組件或者router-view。

  • keep-alive組件在created鉤子中定義了 this.cache 和 this.keys,本質上是去緩存已創建的 vnode,緩存策略采用LRU策略,每次緩存命中時將當前vnode移到緩存數組末尾,需要刪除時則刪除緩存數組第一個vnode。

  • keep-alive組件接收三個props:

    1. include:數組、字符串或者正則表達式,只有匹配的組件才會緩存。

    2. exclude:數組、字符串或者正則表達式,任何匹配的組件都不會被緩存。

    3. max:字符串或數字,指定可以緩存的組件最大個數,如果個數超過max,則銷毀緩存數組中的第一個組件。

  • keep-alive組件子組件渲染機制:

    1. 首次渲染:和普通組件一樣執行正常的init生命周期鉤子函數,同時將生成的vnode緩存到內存中;

    2. 組件切換:切換到新組件時,舊組件不會銷毀,而是變成未激活狀態,即不會執行destroy相關的鉤子函數,而是執行 deactivated 生命周期鉤子函數,如果新組件不在緩存數組中,則執行首次渲染,否則執行緩存渲染;

    3. 緩存渲染:緩存渲染即組件由未激活狀態變成激活狀態,因此不會執行created、mounted等鉤子函數,而是執行 activated 生命周期鉤子函數。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374