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

關(guān)于Vue實例創(chuàng)建的整體流程

 更新時間:2024年06月07日 14:50:08   作者:玉案軒窗  
這篇文章主要介紹了關(guān)于Vue實例創(chuàng)建的整體流程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

前言

本篇是分析new Vue()過程相關(guān)的流程,主要了解如下兩點:

  • new Vue()整體處理流程
  • 掛載處理流程

整體邏輯

使用Vue構(gòu)造函數(shù)創(chuàng)建Vue實例,具體的處理邏輯如下圖:

這里寫圖片描述

從上圖中可以看出,Vue實例的具體處理是定義相關(guān)的內(nèi)部屬性,處理實例選項props、data、methods、computed、watch,以及beforeCreate、created生命周期函數(shù)的執(zhí)行。

這里每一個選項都有不少實現(xiàn)邏輯,這里先不展開,之后會有專門的文章細究。

實際上面邏輯流程中還存在一些細節(jié)點,例如$options的差異處理等,這些需要針對特定的場景來具體聊才能更深的理解,這里先暫時不展開。

el或$mount掛載

對于掛載的處理是在_init即Vue()構(gòu)造函數(shù)中調(diào)用的,具體的處理就是調(diào)用$mount方法,如下:

// el就是掛載點
if (vm.$options.el) vm.$mount(vm.$options.el);

而$mount是定義在Vue原型上的實例方法,這也解釋了Vue掛載的兩種方式:

  • el形式,例如: new Vue({ el: ‘#app’})
  • $mount形式,例如: new Vue().$mount(‘#app’)

$mount方法中具體處理如下:

這里寫圖片描述

從上面可以得出知曉下面幾個結(jié)論:

  • el和$mount兩種方式掛載的緣由,實際上el本質(zhì)上還是調(diào)用$mount方法
  • 若render函數(shù)存在,源碼中會將template/el 轉(zhuǎn)換為render函數(shù)
  • 掛載點應(yīng)該是普通的html元素,而不應(yīng)該是html或body這種特殊的
  • 如果template不存在,實際上會獲取包含掛載點在內(nèi)的outerHTML部分作為template

$mount內(nèi)部是調(diào)用mountComponent函數(shù),該函數(shù)的具體處理是什么呢?具體處理邏輯如下圖:

這里寫圖片描述

從上圖邏輯處理中可知:

  • mountComponent中實際上處理beforeMount、mounted
  • 每個Vue實例都會有相應(yīng)的Watcher實例對應(yīng),Watcher構(gòu)造函數(shù)中vm._watcher和vm._watchers記錄了當(dāng)前實例和watcher對象集合

全局Watcher的具體邏輯

每一個vue實例都對應(yīng)一個watcher實例,這個watcher就是在掛載階段創(chuàng)建的,負責(zé)當(dāng)前實例對應(yīng)的視圖渲染。

其主要邏輯如下:

var updateComponent = function () {
	vm._update(vm._render(), hydrating);
};
new Watcher(vm, updateComponent, noop, {
	before: function before() {
    	if (vm._isMounted || !vm._isDestroyed) {
          callHook(vm, 'beforeUpdate');
        }
    }
}, true)

下面是Watcher構(gòu)造函數(shù)中涉及到的主要邏輯:

    var Watcher = function Watcher (
      vm,
      expOrFn,
      cb,
      options,
      isRenderWatcher
    ) {
      this.vm = vm;
      if (isRenderWatcher) {
        vm._watcher = this;
      }
      // 收集當(dāng)前實例所有watcher對象
      vm._watchers.push(this);
      // options主要處理
      if (options) {
        this.computed = !!options.computed;
      } else {
        this.deep = this.user = this.computed = this.sync = false;
      }
      this.dirty = this.computed; // for computed watchers
      this.deps = [];
      this.newDeps = [];
      this.depIds = new _Set();
      this.newDepIds = new _Set();
      if (typeof expOrFn === 'function') {
        this.getter = expOrFn;
      } 
      if (this.computed) {
        this.value = undefined;
        this.dep = new Dep();
      } else {
        this.value = this.get();
      }
    };

watcher對象創(chuàng)建的過程中,有幾點邏輯需要主要關(guān)注:

  • 每一個vue都對應(yīng)一個watcher實例,該watcher實例負責(zé)視圖渲染,可以通過_watcher屬性得知
	// 是否是渲染W(wǎng)atcher對象
   if (isRenderWatcher) {
    vm._watcher = this;
  }
  • 計算屬性的標(biāo)識即computed
  • 基于computed的不同操作,即get方法是否立即執(zhí)行,非計算屬性的直接就調(diào)用了this.get()方法

Watcher對象中g(shù)et方法是非常重要的邏輯,其主要邏輯可以歸納如下:

Watcher.prototype.get = function get () {
  pushTarget(this);
  var value;
  var vm = this.vm;
  try {
    value = this.getter.call(vm, vm);
  } catch (e) {
  	// 相關(guān)代碼
  } finally {
  	// 支持Watcher對象
    if (this.deep) {
      traverse(value);
    }
    popTarget();
    this.cleanupDeps();
  }
  return value
};

實際通過get方法的邏輯可以得到幾個主要邏輯:

  • pushTarget和PopTarget的設(shè)置
  • 執(zhí)行對應(yīng)的getter函數(shù)
  • watch deep選項的支持邏輯

對于全局Watcher,這里的getter函數(shù)就是執(zhí)行其對應(yīng)的render函數(shù)渲染出來視圖。而watch deep選項則是Vue watch API的使用內(nèi)容,這里暫不展開。

實際上最主要的就是pushTarget相關(guān)的邏輯了,實際上這涉及到一個非常重要的屬性Dep.target。

Dep.target

Dep.target,該屬性是依賴收集關(guān)鍵點之一。

通過Vue源碼知道,Dep.target的改變途徑只有兩個,即pushTarget和popTarget。

    function pushTarget(target) {
      if (Dep.target) targetStack.push(Dep.target);
      Dep.target = target;
    }
    function popTarget() {
      Dep.target = targetStack.pop();
    }

而Vue data中每個屬性的獲取都會檢驗Dep.target是否存在。

只有Dep.target存在下才會去調(diào)用dep.depend()方法來做相關(guān)的處理,而pushTarget和popTarget就是關(guān)鍵了。

Vue源碼中調(diào)用pushTarget函數(shù)實際上就4處:

  • handleError:處理錯誤情況的方法
  • callHook:生命周期函數(shù)調(diào)用
  • Watcher.prototype.get:Watcher對象get實例方法
  • getData:初始化data時當(dāng)data為函數(shù)會調(diào)用getData方法

從上面的pushTarget函數(shù)的邏輯可知會傳遞target參數(shù),pushTarget會保存當(dāng)前Dep.target到數(shù)組(模擬棧結(jié)構(gòu))中。

上面4處調(diào)用pushTarget只有一處傳遞的非空的target,即Watcher.prototype.get。

對于Dep.target需要注意的是:

  • Dep.target只有三種值:null、undefined、watcher對象
  • pushTarget和popTarget是改變Dep.target的唯一途徑

而通過pushTarget可以知道targetStack只會保存watcher對象。通過Vue源碼可知pushTarget和popTarget總是一起搭配出現(xiàn)的,實際上主要作用就是:

在使用pushTarget的地方臨時修改Dep.target的值,已滿足相關(guān)條件

明確下這里的相關(guān)條件,實際上通過源碼中Dep.target使用位置來判斷是可以清晰得到結(jié)論的,即:

Dep.target判斷操作共有3處:

  • defineReactive的get函數(shù)中
  • Watcher.prototype.depend
  • Dep.prototype.depend

從上面可知Dep.target是為watcher對象服務(wù)的,實際上通過Vue響應(yīng)式原理的描述(Dep與Watcher是相關(guān)關(guān)聯(lián)的從而構(gòu)成響應(yīng)式非常重要的一部分),也可以證明Dep.target指向Watcher對象。

Watcher.prototype.get是唯一傳遞了非空target了,而Dep.target值也可能為null、undefined。而=非watcher之外的Dep.target的操作都將Dep.target臨時設(shè)置為undefined,是為了避免執(zhí)行涉及到watcher相關(guān)邏輯。

結(jié)合整體代碼可知:

當(dāng)執(zhí)行g(shù)et函數(shù)時,Dep.target始終是對應(yīng)的watcher對象

總結(jié)

通過對Vue實例創(chuàng)建過程的整體分析,可知其主要的處理邏輯:

  • 執(zhí)行Vue構(gòu)造函數(shù),開始初始化工作
  • 創(chuàng)建相關(guān)實例屬性,例如options、uid
  • 相關(guān)選項初始化工作,例如狀態(tài)(data選項、computed、methods等)、事件相關(guān)等
  • 執(zhí)行beforeCreate、created生命周期函數(shù)
  • el和$mount兩種掛載背后的處理

$mount -> mountComponent -> new Watcher() -> _render()執(zhí)行渲染視圖

每一個Vue實例都對應(yīng)一個watcher實例,該watcher實例是用于控制視圖渲染的

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • nuxt踩坑之Vuex狀態(tài)樹的模塊方式使用詳解

    nuxt踩坑之Vuex狀態(tài)樹的模塊方式使用詳解

    這篇文章主要介紹了nuxt踩坑之Vuex狀態(tài)樹的模塊方式使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Vue Router中應(yīng)用中間件的方法

    Vue Router中應(yīng)用中間件的方法

    這篇文章主要介紹了Vue Router中應(yīng)用中間件的方法,文中講解非常細致,幫助大家更好的理解和學(xué)習(xí)vue router,感興趣的朋友可以了解下
    2020-08-08
  • vue-admin-box第一步npm?install時報錯的處理

    vue-admin-box第一步npm?install時報錯的處理

    這篇文章主要介紹了vue-admin-box第一步npm?install時報錯的處理方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Vue3中的defineExpose函數(shù)用法深入解析

    Vue3中的defineExpose函數(shù)用法深入解析

    這篇文章主要介紹了Vue3中的defineExpose函數(shù)用法的相關(guān)資料,defineExpose是Vue3中用于在模式下暴露組件內(nèi)部屬性和方法的輔助函數(shù),它允許父組件通過ref訪問子組件的暴露內(nèi)容,提高組件間的交互能力并保持封裝性,需要的朋友可以參考下
    2025-01-01
  • Vue手寫實現(xiàn)組件初渲染

    Vue手寫實現(xiàn)組件初渲染

    這篇文章主要介紹了Vue手寫實現(xiàn)組件初渲染,在Vue進行文本編譯之后,會得到代碼字符串生成的render函數(shù),本文會基于render函數(shù)展開主題相關(guān)內(nèi)容,感興趣的朋友可以參考一下
    2022-08-08
  • Vue2遷移Rsbuild詳細步驟

    Vue2遷移Rsbuild詳細步驟

    Rsbuild,一個基于Rspack的高效Web構(gòu)建工具,將Rspack的強大功能與易用性相結(jié)合,是你項目搭建的不二之選,Rsbuild不僅提供了開箱即用的體驗,還引入了高性能的構(gòu)建機制,本文給大家介紹了Vue2遷移Rsbuild詳細步驟,需要的朋友可以參考下
    2024-10-10
  • Vue實現(xiàn)生成本地Json文件功能方式

    Vue實現(xiàn)生成本地Json文件功能方式

    這篇文章主要介紹了Vue實現(xiàn)生成本地Json文件功能方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 詳解windows下vue-cli及webpack 構(gòu)建網(wǎng)站(二)導(dǎo)入bootstrap樣式

    詳解windows下vue-cli及webpack 構(gòu)建網(wǎng)站(二)導(dǎo)入bootstrap樣式

    這篇文章主要介紹了詳解windows下vue-cli及webpack 構(gòu)建網(wǎng)站(二)導(dǎo)入bootstrap樣式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 詳解如何使用Vue實現(xiàn)圖像識別和人臉對比

    詳解如何使用Vue實現(xiàn)圖像識別和人臉對比

    隨著人工智能的發(fā)展,圖像識別和人臉識別技術(shù)已經(jīng)被廣泛應(yīng)用于各種應(yīng)用程序中,Vue為我們提供了許多實用工具和庫,可以幫助我們在應(yīng)用程序中進行圖像識別和人臉識別,在本文中,我們將介紹如何使用Vue進行圖像識別和人臉對比,需要的朋友可以參考下
    2023-06-06
  • Vue3中的組件數(shù)據(jù)懶加載

    Vue3中的組件數(shù)據(jù)懶加載

    這篇文章主要介紹了Vue3中的組件數(shù)據(jù)懶加載問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評論