亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言

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

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

整體邏輯

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

這里寫圖片描述

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

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

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

el或$mount掛載

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

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

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

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

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

這里寫圖片描述

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

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

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

這里寫圖片描述

從上圖邏輯處理中可知:

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

全局Watcher的具體邏輯

每一個(gè)vue實(shí)例都對(duì)應(yīng)一個(gè)watcher實(shí)例,這個(gè)watcher就是在掛載階段創(chuàng)建的,負(fù)責(zé)當(dāng)前實(shí)例對(duì)應(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)前實(shí)例所有watcher對(duì)象
      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對(duì)象創(chuàng)建的過程中,有幾點(diǎn)邏輯需要主要關(guān)注:

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

Watcher對(duì)象中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對(duì)象
    if (this.deep) {
      traverse(value);
    }
    popTarget();
    this.cleanupDeps();
  }
  return value
};

實(shí)際通過get方法的邏輯可以得到幾個(gè)主要邏輯:

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

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

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

Dep.target

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

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

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

而Vue data中每個(gè)屬性的獲取都會(huì)檢驗(yàn)Dep.target是否存在。

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

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

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

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

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

對(duì)于Dep.target需要注意的是:

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

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

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

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

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

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

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

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

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

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

總結(jié)

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

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

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

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

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

相關(guān)文章

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

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

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

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

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

    vue-admin-box第一步npm?install時(shí)報(bào)錯(cuò)的處理

    這篇文章主要介紹了vue-admin-box第一步npm?install時(shí)報(bào)錯(cuò)的處理方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    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手寫實(shí)現(xiàn)組件初渲染

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

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

    Vue2遷移Rsbuild詳細(xì)步驟

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

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

    這篇文章主要介紹了Vue實(shí)現(xiàn)生成本地Json文件功能方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    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樣式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 詳解如何使用Vue實(shí)現(xiàn)圖像識(shí)別和人臉對(duì)比

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

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

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

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

最新評(píng)論