人人都能懂的Vue源碼系列—08—initLifecycle

上篇文章,咱們講了vm._renderProxy相關的內容。主要是經過Proxy爲咱們vm屬性添加一些自定義的行爲。今天咱們回到init方法中,爲你們講解initLifecycle。
initLifeCycle方法用來初始化一些生命週期相關的屬性,以及爲parent,child等屬性賦值,來看源碼。html

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
}

一行一行分析vue

const options = vm.$options

把mergeOptions後的options賦值給options變量。react

// 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)
  }

咱們注意到,vue做者對這段代碼提供了一行註釋api

locate first non-abstract parent

定位第一個"非抽象"的父組件,注意非抽象這三個字。什麼是非抽象呢?最初本身也很疑惑,最後在vue文檔中找到了答案。
抽象組件數組

抽象組件的定義如上圖所示,注意這句話,不會出如今父組件鏈中。明白了這點咱們再去看上面的代碼就不會有那麼迷糊了。ide

let parent = options.parent
if (parent && !options.abstract) {
    ... 
}

當前vm實例有父實例parent,則賦值給parent變量。若是父實例存在,且該實例不是抽象組件。則執行下面代碼ui

while (parent.$options.abstract && parent.$parent) {
  parent = parent.$parent
}
parent.$children.push(vm)

注意while循環內的條件parent.$options.abstract && parent.$parent,若是父實例parent是抽象組件,則繼續找parent上的parent。直到找到非抽象組件爲止。以後把當前vm實例push到定位的第一個非抽象parent的$children屬性上。這樣咱們就說完了怎麼找vm的parent屬性。
以後咱們回到initLifecycle繼續往下看this

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

這些代碼都是爲vm一些屬性賦值。這些屬性的做用以下表。spa

名稱 說明
$parent 指定已建立的實例之父實例,在二者之間創建父子關係。子實例能夠用 this.$parent 訪問父實例,子實例被推入父實例的 $children 數組中。
$root 當前組件樹的根 Vue 實例。若是當前實例沒有父實例,此實例將會是其本身。
$children 當前實例的直接子組件。須要注意 $children 並不保證順序,也不是響應式的。
$refs 一個對象,持有已註冊過 ref 的全部子組件。
_watcher 組件實例相應的 watcher 實例對象。
_inactive 表示keep-alive中組件狀態,如被激活,該值爲false,反之爲true。
_directInactive 也是表示keep-alive中組件狀態的屬性。
_isMounted 當前實例是否完成掛載(對應生命週期圖示中的mounted)。
_isDestroyed 當前實例是否已經被銷燬(對應生命週期圖示中的destroyed)。
_isBeingDestroyed 當前實例是否正在被銷燬,尚未銷燬完成(介於生命週期圖示中deforeDestroy和destroyed之間)。

initLifecycle方法的邏輯比較簡單,主要對vue實例一些屬性進行賦值。因此這裏就不畫流程圖來進行說明了。下篇文章咱們主要講initEvents方法,敬請期待。code

相關文章
相關標籤/搜索