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

資訊專欄INFORMATION COLUMN

vue之initComputed模塊源碼說明

scq000 / 675人閱讀

摘要:要想理解原理就得看源碼,最近網(wǎng)上也找了好多初始化方法個(gè)惡魔。。。因?yàn)橐彩茄驖u進(jìn)的理解,對(duì)計(jì)算屬性的初始化有幾處看得不是很明白,網(wǎng)上也都是含糊其辭的要想深入必須深入。。。

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

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

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

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

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)建一個(gè)訂閱者,為了之后收集依賴
      * 將例子中的num、lastNum和計(jì)算屬性comNum進(jìn)行綁定
      * 也就是說在一個(gè)deps中有兩個(gè)dep,其中的subs分別是
      * dep1.subs:[watcher(num),watcher(comNum)]
      * dep2.subs:[watcher(lastNum),watcher(comNum)]
      * dep3........
      * 請(qǐng)看前面的例子,頁面html中并沒有渲染{{lastNum}};按理說就不會(huì)執(zhí)行l(wèi)astNum的getter
      * 從而就不會(huì)和計(jì)算屬性進(jìn)行關(guān)聯(lián)綁定,如果更改lastNum就不會(huì)觸發(fā)dep2的notify()發(fā)布
      * 自然也就不會(huì)在頁面看到comNum有所變化,但是運(yùn)行后卻不是這樣,為什么呢
      * 這就引出這個(gè)initComputed的下面方法了---依賴收集(watcher.prototype.depend)!
      * 當(dāng)時(shí)也是看了好久才知道這個(gè)depend方法的作用,后面再說
      * 首先先來提個(gè)頭,就是下面代碼中watcher中這個(gè)getter
      * 其實(shí)就是function comNum() {return this.num+"-computed-"+this.lastNum;}}
      * 而這個(gè)getter什么時(shí)候執(zhí)行呢,會(huì)在Watcher.prototype.evaluate()方法中執(zhí)行
      * 所以watcher中的evaluate()與depend()兩個(gè)方法都與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)過判斷后定義計(jì)算屬性---(關(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方法

這個(gè)方法比較簡單主要就是將計(jì)算屬性綁定到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 求計(jì)算屬性的值---利用上面說的調(diào)用watcher.evalute()方法,執(zhí)行watcher中的getter 2 依賴收集綁定,這點(diǎn)最重要,就是上面說過的如果沒有在html中對(duì)計(jì)算屬性相關(guān)聯(lián)的data屬性(lastNum)進(jìn)行頁面渲染的話,watcher.depend()此方法就會(huì)執(zhí)行這個(gè)依賴收集綁定的作用dep.subs[watcher(計(jì)算屬性),watcher(計(jì)算關(guān)聯(lián)屬性1),...],這樣的話當(dāng)你更改lastNum就會(huì)觸發(fā)對(duì)應(yīng)的dep.notify()方法發(fā)布通知訂閱者執(zhí)行update,進(jìn)行數(shù)據(jù)更新了,而如果將watcher.depend()方法注釋掉,而頁面中將lastNum渲染({{lastNum}}),此時(shí)watcher.evalute()會(huì)執(zhí)行watcher.get從而將此計(jì)算watcher推入dep.target中,而渲染lastNum執(zhí)行g(shù)etter的時(shí)候就會(huì)將此watcher加入依賴,所以也會(huì)將lastNum和計(jì)算屬性關(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()方法,此時(shí)deps中沒有dep:id4
其實(shí)dep:id4在內(nèi)存中已經(jīng)定義好了但是沒有加入到deps中(因?yàn)闆]有進(jìn)行依賴收集)
而dep:id5和id6就是上面的數(shù)組和遞歸數(shù)組中元素的dep

dep:id3 就是

這下是不是很清楚了

圖組二

進(jìn)行依賴收集后的deps

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/92608.html

相關(guān)文章

  • vueinitComputed模塊源碼說明

    摘要:要想理解原理就得看源碼,最近網(wǎng)上也找了好多初始化方法個(gè)惡魔。。。因?yàn)橐彩茄驖u進(jìn)的理解,對(duì)計(jì)算屬性的初始化有幾處看得不是很明白,網(wǎng)上也都是含糊其辭的要想深入必須深入。。。 要想理解原理就得看源碼,最近網(wǎng)上也找了好多vue初始化方法(8個(gè)init惡魔。。。) 因?yàn)橐彩茄驖u進(jìn)的理解,對(duì)initComputed計(jì)算屬性的初始化有幾處看得不是很明白,網(wǎng)上也都是含糊其辭的(要想深入必須深入。。...

    zhaot 評(píng)論0 收藏0
  • vue源碼分析系列響應(yīng)式數(shù)據(jù)(一)

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

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

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

    shenhualong 評(píng)論0 收藏0
  • Vue原理】Computed - 源碼

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

    solocoder 評(píng)論0 收藏0
  • vue源碼-對(duì)于「計(jì)算屬性」的理解

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

    xiaochao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<