生命週期鉤子是怎麼在一起的?

小為子發表於2019-03-29

生命週期鉤子選項的合併策略

生命週期鉤子選項:

function mergeHook (
  parentVal: ?Array<Function>,
  childVal: ?Function | ?Array<Function>
): ?Array<Function> {
  return childVal
    ? parentVal
      ? parentVal.concat(childVal)
      : Array.isArray(childVal)
        ? childVal
        : [childVal]
    : parentVal
}

LIFECYCLE_HOOKS.forEach(hook => {
  strats[hook] = mergeHook
})
複製程式碼

這是用來合併生命週期鉤子的,先看看forEach語句:

使用 forEach 遍歷 LIFECYCLE_HOOKS 常量,那說明這個常量應該是一個陣列, 我們再來看看

LIFECYCLE_HOOKS常量是什麼複製程式碼
export const LIFECYCLE_HOOKS = [
  'beforeCreate',
  'created',
  'beforeMount',
  'mounted',
  'beforeUpdate',
  'updated',
  'beforeDestroy',
  'destroyed',
  'activated',
  'deactivated',
  'errorCaptured'
]
複製程式碼

  LIFECYCLE_HOOKS 常量實際上是由與生命週期鉤子同名的字串組成的陣列

forEach 語句,它的作用就是在 strats 策略物件上新增用來合併各個生命週期鉤子選項的策略函式,並且這些生命週期鉤子選項的策略函式相同:

都是 mergeHook 函式

return childVal
    ? parentVal
      ? parentVal.concat(childVal)
      : Array.isArray(childVal)
        ? childVal
        : [childVal]
    : parentVal
複製程式碼

  

mergeHook 函式內部處理操作,整體上是由三元運算子構成

return (是否有 childVal,即判斷元件的選項中是否有對應名字的生命週期鉤子函式)
  ? 如果有 childVal 則判斷是否有 parentVal
    ? 如果有 parentVal 則使用 concat 方法將二者合併為一個陣列
    : 如果沒有 parentVal 則判斷 childVal 是不是一個陣列
      ? 如果 childVal 是一個陣列則直接返回
      : 否則將其作為陣列的元素,然後返回陣列
  : 如果沒有 childVal 則直接返回 parentVal
複製程式碼

  也就是說判斷子選項和父選項是否有,然後進行對應的處理,

如果子選項和父選項都有 則合併成為一個陣列 等。。。。

它判斷是否有 childVal,即元件的選項是否寫了生命週期鉤子函式,如果沒有則直接返回了 parentVal

如果有 parentVal 那麼其一定是陣列,如果沒有 parentVal 那麼 strats[hooks] 函式根本不會執行

接下來看看幾種例項:更加明確的學習生命週期選項策略:

new Vue({
  created: function () {
    console.log('created')
  }
})
複製程式碼

  strats.created 策略函式來講 ,created就是childVal,它是一個函式。parentVal 應該是 Vue.options.created,但 Vue.options.created 是不存在的,所以最終經過 strats.created 函式的處理將返回一個陣列:

options.created = [
  function () {
    console.log('created')
  }  
]
複製程式碼

 看下一個例子:

const Parent = Vue.extend({
  created: function () {
    console.log('parentVal')
  }
})

const Child = new Parent({
  created: function () {
    console.log('childVal')
  }
})
複製程式碼

  Child 是通過new parent生成的 Child 就是childVal, Parent 就是parentVal

childVal:

created: function () {
  console.log('childVal')
}
複製程式碼

 parentVal:(Parent.options.created)

Parent.options.created = [
  created: function () {
    console.log('parentVal')
  }
]
複製程式碼

  這個例子有 childVal,又有 parentVal,根據mergeHooks 函式:

parentVal.concat(childVal),將 parentValchildVal 合併成一個陣列

  created: function () {
    console.log('parentVal')
  },
  created: function () {
    console.log('childVal')
  }
]
複製程式碼

  

 Array.isArray(childVal)]?
這一段三元運算代表什麼?
說明vue 生命週期鉤子是可以寫成陣列的,是不是很驚訝 很神奇,從未有過的姿勢,如此的爽!
複製程式碼
new Vue({
  created: [
    function () {
      console.log('first')
    },
    function () {
      console.log('second')
    },
    function () {
      console.log('third')
    }
  ]
})
複製程式碼

  vue原始碼讀起來真雞兒爽!!!

 複製程式碼


相關文章