国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

vue之initComputed模塊源碼說明

zhaot / 1271人閱讀

摘要:要想理解原理就得看源碼,最近網(wǎng)上也找了好多初始化方法個惡魔。。。因為也是循序漸進的理解,對計算屬性的初始化有幾處看得不是很明白,網(wǎng)上也都是含糊其辭的要想深入必須深入。。。

要想理解原理就得看源碼,最近網(wǎng)上也找了好多vue初始化方法(8個init惡魔。。。)

因為也是循序漸進的理解,對initComputed計算屬性的初始化有幾處看得不是很明白,網(wǎng)上也都是含糊其辭的(要想深入必須深入。。。),所以debug了好幾天,才算是有點頭緒,現(xiàn)在寫出來即幫自己再次理下思路,也可以讓大佬指出錯誤

首先,基本的雙向綁定原理就不說了,可以去搜下相關(guān)教程,還是要先理解下簡單的例子

進入正題,先來看下initComputed的源碼結(jié)構(gòu),這之前還是先放一個例子也好說明

function initComputed (vm, computed) {
  console.log("%cinitComputed","font-size:20px;border:1px solid black")
  var watchers = vm._computedWatchers = Object.create(null);
  // computed properties are just getters during SSR
  var isSSR = isServerRendering();

  for (var key in computed) {
    var userDef = computed[key];
    var getter = typeof userDef === "function" ? userDef : userDef.get;
    if ("development" !== "production" && getter == null) {
      warn(
        ("Getter is missing for computed property "" + key + ""."),
        vm
      );
    }
    //minxing---console
    console.log("%cinitComputed 定義watchers[key]=new Watcher(vm getter noop computedWatcherOptions)","color:white;padding:5px;background:black");
   
    if (!isSSR) {
      // create internal watcher for the computed property.
      /**
      * 熟悉的newWatcher,創(chuàng)建一個訂閱者,為了之后收集依賴
      * 將例子中的num、lastNum和計算屬性comNum進行綁定
      * 也就是說在一個deps中有兩個dep,其中的subs分別是
      * dep1.subs:[watcher(num),watcher(comNum)]
      * dep2.subs:[watcher(lastNum),watcher(comNum)]
      * dep3........
      * 請看前面的例子,頁面html中并沒有渲染{{lastNum}};按理說就不會執(zhí)行l(wèi)astNum的getter
      * 從而就不會和計算屬性進行關(guān)聯(lián)綁定,如果更改lastNum就不會觸發(fā)dep2的notify()發(fā)布
      * 自然也就不會在頁面看到comNum有所變化,但是運行后卻不是這樣,為什么呢
      * 這就引出這個initComputed的下面方法了---依賴收集(watcher.prototype.depend)!
      * 當時也是看了好久才知道這個depend方法的作用,后面再說
      * 首先先來提個頭,就是下面代碼中watcher中這個getter
      * 其實就是function comNum() {return this.num+"-computed-"+this.lastNum;}}
      * 而這個getter什么時候執(zhí)行呢,會在Watcher.prototype.evaluate()方法中執(zhí)行
      * 所以watcher中的evaluate()與depend()兩個方法都與initComputed相關(guān)
      */
      watchers[key] = new Watcher(
        vm,
        getter || noop,
        noop,
        computedWatcherOptions
      );
    }

    // component-defined computed properties are already defined on the
    // component prototype. We only need to define computed properties defined
    // at instantiation here.
    // 經(jīng)過判斷后定義計算屬性---(關(guān)聯(lián)到vm的data上面)
    if (!(key in vm)) {
      defineComputed(vm, key, userDef);
    } else {
      if (key in vm.$data) {
        warn(("The computed property "" + key + "" is already defined in data."), vm);
      } else if (vm.$options.props && key in vm.$options.props) {
        warn(("The computed property "" + key + "" is already defined as a prop."), vm);
      }
    }
  }
}
defineComputed方法

這個方法比較簡單主要就是將計算屬性綁定到vm上,重要的下面的createComputedGetter方法

function defineComputed (
  target,
  key,
  userDef
) {
  console.log("%cdefineComputed","font-size:20px;border:1px solid black")
  var shouldCache = !isServerRendering();
  if (typeof userDef === "function") {
    sharedPropertyDefinition.get = shouldCache
      ? createComputedGetter(key)
      : userDef;
    sharedPropertyDefinition.set = noop;
  } else {
    sharedPropertyDefinition.get = userDef.get
      ? shouldCache && userDef.cache !== false
        ? createComputedGetter(key)
        : userDef.get
      : noop;
    sharedPropertyDefinition.set = userDef.set
      ? userDef.set
      : noop;
  }
  if ("development" !== "production" &&
      sharedPropertyDefinition.set === noop) {
    sharedPropertyDefinition.set = function () {
      warn(
        ("Computed property "" + key + "" was assigned to but it has no setter."),
        this
      );
    };
  }
  Object.defineProperty(target, key, sharedPropertyDefinition);
}
function createComputedGetter (key) {
  console.log("createComputedGetter key",key);
  return function computedGetter () {
    var watcher = this._computedWatchers && this._computedWatchers[key];
    if (watcher) {
      if (watcher.dirty) {
        watcher.evaluate();
      }
      if (Dep.target) {
        watcher.depend();
      }
      return watcher.value
    }
  }
}
createComputedGetter方法,主要做了兩件事 1 求計算屬性的值---利用上面說的調(diào)用watcher.evalute()方法,執(zhí)行watcher中的getter 2 依賴收集綁定,這點最重要,就是上面說過的如果沒有在html中對計算屬性相關(guān)聯(lián)的data屬性(lastNum)進行頁面渲染的話,watcher.depend()此方法就會執(zhí)行這個依賴收集綁定的作用dep.subs[watcher(計算屬性),watcher(計算關(guān)聯(lián)屬性1),...],這樣的話當你更改lastNum就會觸發(fā)對應的dep.notify()方法發(fā)布通知訂閱者執(zhí)行update,進行數(shù)據(jù)更新了,而如果將watcher.depend()方法注釋掉,而頁面中將lastNum渲染({{lastNum}}),此時watcher.evalute()會執(zhí)行watcher.get從而將此計算watcher推入dep.target中,而渲染lastNum執(zhí)行g(shù)etter的時候就會將此watcher加入依賴,所以也會將lastNum和計算屬性關(guān)聯(lián)到dep中
function createComputedGetter (key) {
  console.log("createComputedGetter key",key);
  return function computedGetter () {
    var watcher = this._computedWatchers && this._computedWatchers[key];
    if (watcher) {
      if (watcher.dirty) {
        console.log("createComputedGetter watcher evaluate===========");
        //求值
        watcher.evaluate();
      }
      if (Dep.target) {
        console.log("createComputedGetter watcher depend===========");
        //依賴收集
        watcher.depend();
      }
      console.log("%ccreateComputedGetter watcher.value is","color:blue;font-size:40px",watcher.value);
      return watcher.value
    }
  }
}

為了更好的說明下,截兩張圖(都是基于最上面的html配置哦)

圖組一

注釋掉watcher.depend()方法,此時deps中沒有dep:id4
其實dep:id4在內(nèi)存中已經(jīng)定義好了但是沒有加入到deps中(因為沒有進行依賴收集)
而dep:id5和id6就是上面的數(shù)組和遞歸數(shù)組中元素的dep

dep:id3 就是

這下是不是很清楚了

圖組二

進行依賴收集后的deps

綜上,計算屬性基本的原理就是這樣了,主要是自己的理解,有不對的地方還請指出,哎,還是寫代碼舒服點,打字描述太累。。。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/51731.html

相關(guān)文章

  • vueinitComputed模塊源碼說明

    摘要:要想理解原理就得看源碼,最近網(wǎng)上也找了好多初始化方法個惡魔。。。因為也是循序漸進的理解,對計算屬性的初始化有幾處看得不是很明白,網(wǎng)上也都是含糊其辭的要想深入必須深入。。。 要想理解原理就得看源碼,最近網(wǎng)上也找了好多vue初始化方法(8個init惡魔。。。) 因為也是循序漸進的理解,對initComputed計算屬性的初始化有幾處看得不是很明白,網(wǎng)上也都是含糊其辭的(要想深入必須深入。。...

    scq000 評論0 收藏0
  • vue源碼分析系列響應式數(shù)據(jù)(一)

    摘要:代碼初始化部分一個的時候做了什么當我們一個時,實際上執(zhí)行了的構(gòu)造函數(shù),這個構(gòu)造函數(shù)內(nèi)部掛載了很多方法,可以在我的上一篇文章中看到。合并構(gòu)造函數(shù)上掛載的與當前傳入的非生產(chǎn)環(huán)境,包裝實例本身,在后期渲染時候,做一些校驗提示輸出。 概述 在使用vue的時候,data,computed,watch是一些經(jīng)常用到的概念,那么他們是怎么實現(xiàn)的呢,讓我們從一個小demo開始分析一下它的流程。 dem...

    liujs 評論0 收藏0
  • vue源碼分析系列響應式數(shù)據(jù)(三)

    摘要:并在內(nèi)執(zhí)行了函數(shù),在函數(shù)內(nèi)部,訪問了。至此知道了它依賴于。需要根據(jù)最新的計算。本例中收集到了依賴并且也被告知觀察了他們。文章鏈接源碼分析系列源碼分析系列之環(huán)境搭建源碼分析系列之入口文件分析源碼分析系列之響應式數(shù)據(jù)一源碼分析系列之響應式數(shù)據(jù)二 前言 上一節(jié)著重講述了initData中的代碼,以及數(shù)據(jù)是如何從data中到視圖層的,以及data修改后如何作用于視圖。這一節(jié)主要記錄initCo...

    shenhualong 評論0 收藏0
  • Vue原理】Computed - 源碼

    摘要:被讀取,包裝的函數(shù)觸發(fā),第一次會進行計算被調(diào)用,進而被調(diào)用,被設置為,舊值頁面被緩存起來。計算會讀取,此時就收集到同時也會保存到的依賴收集器用于下一步。 寫文章不容易,點個贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學習吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下...

    solocoder 評論0 收藏0
  • vue源碼-對于「計算屬性」的理解

    摘要:源碼對于計算屬性的理解這是我最近學習源碼的一個個人總結(jié)和理解,所以可能并不適合每一位讀者本文的整體脈絡如下,首先盡可能去掉細節(jié),對計算屬性源碼的大致實現(xiàn)有一個了解,然后舉一例子,分別談談計算屬性依賴收集和派發(fā)更新的流程。 vue源碼-對于「計算屬性」的理解 這是我最近學習vue源碼的一個個人總結(jié)和理解,所以可能并不適合每一位讀者 本文的整體脈絡如下,首先盡可能去掉細節(jié),對計算屬性源碼的...

    xiaochao 評論0 收藏0

發(fā)表評論

0條評論

zhaot

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<