欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue生命周期函數(shù)調(diào)用詳解

 更新時間:2022年08月15日 10:50:08   作者:夏日  
這篇文章主要介紹了Vue生命周期函數(shù)調(diào)用詳解,本文將實現(xiàn)Vue生命周期相關(guān)代碼的核心邏輯,從源碼層面來理解生命周期,感興趣的小伙伴可以參考一下

生命周期

Vue為用戶提供了許多生命周期鉤子函數(shù),可以讓用戶在組件運行的不同階段書寫自己的邏輯。

那么Vue內(nèi)部到底是如何處理生命周期函數(shù)的呢?Vue的生命周期究竟是在代碼運行的哪個階段執(zhí)行呢?本文將實現(xiàn)Vue生命周期相關(guān)代碼的核心邏輯,從源碼層面來理解生命周期。

Vue.mixin

在介紹生命周期之前,我們先來看下Vue.mixin

Vue.mixinVue的全局混合器,它影響Vue創(chuàng)建的每一個實例,會將mixin 中傳入的配置項與組件實例化時的配置項按照一定規(guī)則進行合并。對于生命周期鉤子函數(shù),相同名字的生命周期將會合并到一個數(shù)組中,混合器中的鉤子函數(shù)將會先于組件中的鉤子函數(shù)放入到數(shù)組中。在特定時機時,從左到右執(zhí)行數(shù)組中的每一個鉤子函數(shù)。

<div id="app">
</div>
<script>
  // 生命周期:
  Vue.mixin({
    created () {
      console.log('global created');
    }
  });
  const vm = new Vue({
    el: '#app',
    data () {
    },
    created () {
      console.log('component created');
    }
  });
  // global created
  // component created  
</script>

上述代碼會先執(zhí)行Vue.mixin中的created函數(shù),然后再執(zhí)行組件中的created函數(shù)。下面我們看下Vue.mixin是怎么實現(xiàn)。

// src/global-api/index.js
import mergeOptions from '../shared/merge-options';

export function initGlobalApi (Vue) {
  Vue.options = {};
  Vue.mixin = function (mixin) {
    this.options = mergeOptions(this.options, mixin);
  };
}

// src/index.js
function Vue (options) {
  this._init(options);
}

// 初始化全局api
initGlobalApi(Vue);
export default Vue;

scr/index.js中執(zhí)行initGlobalApi方法,會為Vue添加optionsVue.mixin屬性。

Vue.mixin會將調(diào)用該函數(shù)時傳入的配置項與Vue.options中的選項進行合并:

Vue.options = {};
Vue.mixin = function (mixin) {
  // Vue.options = mergeOptions(Vue.options, mixin)
  this.options = mergeOptions(this.options, mixin);
};

Vue.options中會保存所有全局的配置項,如components,directives等。執(zhí)行Vue.mixin之后,Vue.options會和Vue.mixin 中的選項進行合并,之后會在組件初始化時將其和組件實例化時傳入的選項根據(jù)不同的合并策略進行合并,這樣會根據(jù)最終合并后的全局選項和組件選項來創(chuàng)建Vue 實例:

// src/init.js
function initMixin (Vue) {
  Vue.prototype._init = function (options) {
    const vm = this;
    // 在初始化根組件時: vm.constructor.options -> Vue.options
    // 在初始化子組件時: vm.constructor.options -> Sub.options
    // 將局部選項和全局選項進行合并
    vm.$options = mergeOptions(vm.constructor.options, options);
    // some code ...  
  };
  // some code ...  
}

現(xiàn)在關(guān)鍵邏輯來到了mergeOptions,下面來介紹mergeOptions的整體編寫思路以及生命周期的合并過程。

生命周期選項合并

mergeOptions函數(shù)完成了組件中選項合并的邏輯:

const strategies = {};

function defaultStrategy (parentVal, childVal) {
  return childVal === undefined ? parentVal : childVal;
}
const LIFECYCLE_HOOKS = [
  'beforeCreate',
  'created',
  'beforeMount',
  'mounted',
  'beforeUpdate',
  'updated',
  'beforeDestroy',
  'destroyed'
];
function mergeHook (parentVal, childVal) {
  if (parentVal) {
    if (childVal) {
      // concat可以拼接值和數(shù)組,但是相對于push來說,會返回拼接后新數(shù)組,不會改變原數(shù)組
      return parentVal.concat(childVal);
    }
    return parentVal;
  } else {
    return [childVal];
  }
}

LIFECYCLE_HOOKS.forEach(hook => {
  strategies[hook] = mergeHook;
});

function mergeOptions (parent, child) { // 將子選項和父選項合并
  const options = {};

  function mergeField (key) {
    const strategy = strategies[key] || defaultStrategy;
    options[key] = strategy(parent[key], child[key]);
  }

  for (const key in parent) {
    if (parent.hasOwnProperty(key)) {
      mergeField(key);
    }
  }
  for (const key in child) {
    if (child.hasOwnProperty(key) && !parent.hasOwnProperty(key)) {
      mergeField(key);
    }
  }
  return options;
}
export default mergeOptions;

對于不同的選項,Vue會采取不同的合并策略。也就是為strategies添加Vue的各個選項作為key,其對應(yīng)的合并邏輯是一個函數(shù),為strategies[key]的值。如果沒有對應(yīng)key 的話,會采用默認的合并策略defaultStrategy來處理默認的合并邏輯。

這樣可以讓我們不用再用if else來不停為每一個選項進行判斷,使代碼更加簡潔。并且在之后如果需要添加新的合并策略時,只需要添加類似如下代碼即可,更易于維護:

function mergeXXX (parentVal, childVal) {
  return result
}
strategies[xxx] = mergeXXX

對于生命周期,我們會將每個鉤子函數(shù)都通過mergeHook合并為一個數(shù)組:

function mergeHook (parentVal, childVal) {
  if (parentVal) {
    if (childVal) {
      // concat可以拼接值和數(shù)組,但是相對于push來說,會返回拼接后新數(shù)組,不會改變原數(shù)組
      return parentVal.concat(childVal);
    }
    return parentVal;
  } else {
    return [childVal];
  }
}

Vue.mixin中提到例子的合并結(jié)果如下:

現(xiàn)在我們已經(jīng)成功將生命周期處理成了數(shù)組,接下來便到了執(zhí)行數(shù)組中的所有鉤子函數(shù)的邏輯了。

調(diào)用生命周期函數(shù)

完成上述代碼后,我們已經(jīng)成功將所有合并后的生命周期放到了vm.$options中對應(yīng)的生命周期數(shù)組中:

vm.$options = {
  created: [f1, f2, f3],
  mounted: [f4, f5, f6]
  // ...
}

想要執(zhí)行某個生命周期函數(shù),可以用它的名字從vm.$options找到其對應(yīng)的函數(shù)執(zhí)行。為了方便生命周期的調(diào)用,封裝了一個callHook函數(shù)來幫我們做這些操作:

// src/lifecycle.js
export function callHook (vm, hook) {
  const handlers = vm.$options[hook];
  if (handlers) {
    handlers.forEach(handler => handler.call(vm));
  }
}

對于目前我們已經(jīng)完成的代碼,可以在如下位置添加生命周期鉤子函數(shù)的調(diào)用:

此時,用戶在使用時傳入的beforeCreate,created,beforeMount,Mounted鉤子函數(shù)就可以正確執(zhí)行了。

  • beforeCreate:在組件初始化狀態(tài)initState之前執(zhí)行,此時不能訪問props,methods,data,computed等實例上的屬性
  • created:組件初始化狀態(tài)后執(zhí)行,此時props,methods,data等選項已經(jīng)初始化完畢,可以通過實例來直接訪問
  • beforeMount: 組件過載之前執(zhí)行
  • mounted: 組件掛載之后執(zhí)行,即使用實例上最新的data生成虛擬DOM,然后將虛擬DOM掛載到真實DOM之后執(zhí)行。

結(jié)語

生命周期函數(shù)本質(zhì)上就是我們在配置項中傳入回調(diào)函數(shù),Vue會將我們傳入的配置項收集到數(shù)組中,然后在特定時機統(tǒng)一執(zhí)行。

Vue的生命周期從定義到執(zhí)行一共經(jīng)歷了如下幾個步驟:

  • 在組件實例化時作為選項傳入
  • 首先將Vue.mixin中傳入的配置項和Vue.options中的生命周期函數(shù)合并為一個數(shù)組
  • 將組件實例化時傳入的選項和Vue.options中的生命周期繼續(xù)進行合并
  • 封裝callHook函數(shù),從vm.$options中找到指定生命周期函數(shù)對應(yīng)的數(shù)組
  • 在特定時機執(zhí)行特定的生命周期函數(shù)

到此這篇關(guān)于Vue生命周期函數(shù)調(diào)用詳解的文章就介紹到這了,更多相關(guān)Vue生命周期內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

源碼地址:傳送門

相關(guān)文章

  • vuex 中輔助函數(shù)mapGetters的基本用法詳解

    vuex 中輔助函數(shù)mapGetters的基本用法詳解

    mapGetters輔助函數(shù)僅僅是將 store 中的 getter 映射到局部計算屬性,在組件或界面中不使用mapGetter調(diào)用映射vuex中的getter,在組件或界面中使用mapGetter調(diào)用映射vuex中的getter,具體內(nèi)容跟隨小編一起通過本文學(xué)習(xí)吧 
    2021-07-07
  • 解決vue router組件狀態(tài)刷新消失的問題

    解決vue router組件狀態(tài)刷新消失的問題

    這篇文章主要介紹了vue router組件狀態(tài)刷新消失的問題,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-08-08
  • React和Vue中監(jiān)聽變量變化的方法

    React和Vue中監(jiān)聽變量變化的方法

    這篇文章主要介紹了React和Vue中監(jiān)聽變量變化的方法,本文通過一個場景,父組件傳遞子組件一個A參數(shù),子組件需要監(jiān)聽A參數(shù)的變化轉(zhuǎn)換為state,具體內(nèi)容詳情大家跟隨小編一起通過本文學(xué)習(xí)吧
    2018-11-11
  • 關(guān)于vue項目中搜索節(jié)流的實現(xiàn)代碼

    關(guān)于vue項目中搜索節(jié)流的實現(xiàn)代碼

    這篇文章主要介紹了關(guān)于vue項目中搜索節(jié)流的實現(xiàn)代碼,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • vant實現(xiàn)購物車功能

    vant實現(xiàn)購物車功能

    這篇文章主要為大家詳細介紹了vant實現(xiàn)購物車功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • vue中如何引入jest單元測試

    vue中如何引入jest單元測試

    這篇文章主要介紹了vue中如何引入jest單元測試問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Vue 實現(xiàn)分頁與輸入框關(guān)鍵字篩選功能

    Vue 實現(xiàn)分頁與輸入框關(guān)鍵字篩選功能

    這篇文章主要介紹了Vue 實現(xiàn)分頁+輸入框關(guān)鍵字篩選功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-01-01
  • 詳解vue-cli4 配置不同開發(fā)環(huán)境打包命令

    詳解vue-cli4 配置不同開發(fā)環(huán)境打包命令

    這篇文章主要介紹了vue-cli4 配置不同開發(fā)環(huán)境打包命令,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • Vue項目中使用flow做類型檢測的方法

    Vue項目中使用flow做類型檢測的方法

    這篇文章主要介紹了Vue項目中使用flow做類型檢測的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • vue項目中使用html2canvas解決截圖不全的問題

    vue項目中使用html2canvas解決截圖不全的問題

    本文主要介紹了vue項目中使用html2canvas解決截圖不全的問題
    2023-11-11

最新評論