1. 程式人生 > 其它 >Vue原始碼解析(生命週期篇三)

Vue原始碼解析(生命週期篇三)

技術標籤:vue.js

初始化階段(initLifecycle)

1.前言

  • 上篇文章中,我們介紹了生命週期初始化階段的整體工作流程,以及在該階段都做了哪些事情。我們知道了,在該階段會呼叫一些初始化函式,對Vue例項的屬性、資料等進行初始化工作。那這些初始化函式都初始化了哪些東西以及都怎麼初始化的呢?
  • 接下來我們就把這些初始化函式一一展開介紹,本篇文章介紹第一個初始化函式initLifecycle。

2.initLifecycle函式分析

  • initLifecycle函式的定義位於原始碼的src/core/instance/lifecycle.js中,其程式碼如下:
    export function initLifecycle
    (vm: Component) { const options = vm.$options // locate first non-abstract parent let parent = options.parent if (parent && !options.abstract) { while (parent.$options.abstract && parent.$parent) { parent = parent.$parent } parent.$children.push(vm) } vm.
    $parent = parent vm.$root = parent ? parent.$root : vm vm.$children = [] vm.$refs = {} vm._watcher = null vm._inactive = null vm._directInactive = false vm._isMounted = false vm._isDestroyed = false vm._isBeingDestroyed = false }
  • 可以看到,initLifecycle函式的程式碼量並不多,邏輯也不復雜。其主要是給Vue例項上掛載了一些屬性並設定了預設值,值得一提的是掛載$parent 屬性和$root屬性,下面我們就來逐個分析。
  • 首先是給例項上掛載$parent屬性,這個屬性有點意思,我們先來看看程式碼:
    let parent = options.parent
    if (parent && !options.abstract) {
      while (parent.$options.abstract && parent.$parent) {
        parent = parent.$parent
      }
      parent.$children.push(vm)
    }
    
    vm.$parent = parent
    
  • 程式碼中可以看到,邏輯是這樣子的:如果當前元件不是抽象元件並且存在父級,那麼就通過while迴圈來向上迴圈,如果當前元件的父級是抽象元件並且也存在父級,那就繼續向上查詢當前元件父級的父級,直到找到第一個不是抽象型別的父級時,將其賦值vm.$parent,同時把該例項自身新增進找到的父級的$children屬性中。這樣就確保了在子元件的$parent屬性上能訪問到父元件例項,在父元件的$children屬性上也能訪問子元件的例項。
  • 接著是給例項上掛載$root屬性,如下:
    vm.$root = parent ? parent.$root : vm
    
  • 例項的$root屬性表示當前例項的根例項,掛載該屬性時,首先會判斷如果當前例項存在父級,那麼當前例項的根例項$root屬性就是其父級的根例項$root屬性,如果不存在,那麼根例項$root屬性就是它自己。這很好理解,舉個例子:假如有一個人,他如果有父親,那麼他父親的祖先肯定也是他的祖先,同理,他的兒子的祖先也肯定是他的祖先,我們不需要真正的一層一層的向上遞迴查詢到他祖先本人,只需要知道他父親的祖先是誰然後告訴他即可。如果他沒有父親,那說明他自己就是祖先,那麼他後面的兒子、孫子的$root屬性就是他自己了。
  • 這就是一個自上到下將根例項的$root屬性依次傳遞給每一個子例項的過程。
  • 最後,再初始化了一些其它屬性,因為都是簡單的賦初始值,這裡就不再一一介紹,等後面內容涉及到的時候再介紹。
    vm.$children = []
    vm.$refs = {}
    
    vm._watcher = null
    vm._inactive = null
    vm._directInactive = false
    vm._isMounted = false
    vm._isDestroyed = false
    vm._isBeingDestroyed = false
    

3.總結

  • 本篇文章介紹了初始化階段呼叫的第一個初始化函式——initLifecycle函式。該函式的邏輯非常簡單,就是給例項初始化了一些屬性,包括以$開頭的供使用者使用的外部屬性,也包括以_開頭的供內部使用的內部屬性。

下一篇初始化階段(initEvents)