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

資訊專欄INFORMATION COLUMN

【前端進階基礎】VUE響應式數(shù)據(jù)原理 訂閱-發(fā)布模式解析

陳偉 / 1416人閱讀

摘要:其成員函數(shù)最主要的是和,前者用來設置某個的依賴,后者則用來通知與這個依賴相關的來運行其回調函數(shù)。也就是進行數(shù)據(jù)更新操作。

vue框架的兩個抽象核心:虛擬DOM和相應式數(shù)據(jù)原理

關于虛擬DOM的核心算法,我們上一章已經基本解析過了,詳細的見
React && VUE Virtual Dom的Diff算法統(tǒng)一之路 snabbdom.js解讀

關于響應式數(shù)據(jù)原理,我們先看張圖
你 ‘ (4).png

具體來講,要分以下幾步:

初始化實例對象時運行initState, 建立好props, data 的鉤子以及其對象成員的Observer, 對于computed 屬性,則建立起所有對應的 Watcher 并且通過 Object.defineProperty 在vm對象上設置一個該屬性的 getter。同時還根據(jù)自定義的 watch 來建立相應的 Watcher

執(zhí)行掛載操作,在掛載時建立一個直接對應render(渲染)的 Watcher,并且編譯模板生成 render 函數(shù),執(zhí)行vm._update 來更新 DOM 。

此后每當有數(shù)據(jù)改變,都將通知相應的 Watcher 執(zhí)行回調函數(shù)。

Observer 劫持者
export class Observer {
  value: any;
  dep: Dep;
  vmCount: number; // number of vms that has this object as root $data

  constructor (value: any) {
    this.value = value
    this.dep = new Dep()
    this.vmCount = 0
    def(value, "__ob__", this)
    if (Array.isArray(value)) {
      const augment = hasProto
        ? protoAugment
        : copyAugment
      augment(value, arrayMethods, arrayKeys)
      this.observeArray(value)
    } else {
      this.walk(value)
    }
  }

  /**
   * Walk through each property and convert them into
   * getter/setters. This method should only be called when
   * value type is Object.
   */
  walk (obj: Object) {
    const keys = Object.keys(obj)
    for (let i = 0; i < keys.length; i++) {
      defineReactive(obj, keys[i], obj[keys[i]])
    }
  }

  /**
   * Observe a list of Array items.
   */
  observeArray (items: Array) {
    for (let i = 0, l = items.length; i < l; i++) {
      observe(items[i])
    }
  }
}

首先我們觀察到,new Observer()的時候,會進行類型的判斷

if (Array.isArray(value)) {
      const augment = hasProto
        ? protoAugment
        : copyAugment
      augment(value, arrayMethods, arrayKeys)
      this.observeArray(value)
    } else {
      this.walk(value)
    }

如果是數(shù)組類型則會遞歸調用,建立依賴體系
否則則調用walk()函數(shù)去利用Object.defineProperty簡歷依賴

那么defineReactive是如何實現(xiàn)的呢,如下

//省略了部分代碼
export function defineReactive (
 obj: Object,
 key: string,
 val: any,
 customSetter?: ?Function,
 shallow?: boolean
) {
  const dep = new Dep()
  ...
  Object.defineProperty(obj, key, {
      ...
      get: function reactiveGetter () {
        ...
        dep.depend()
        ...
        return value
      },
      set: function reactiveSetter (newVal) {
        ...
        dep.notify()
      }
    })
}

攔截器會分別在getter和setter上設置中間件去維護dep數(shù)組中的依賴關系

dep.depend()

dep.notify()

字面意思非常明顯,分別用于增加依賴和通知依賴變化關系

Dep (dependency // 依賴)
class Dep {
  static target: ?Watcher;
  id: number;
  subs: Array;

  constructor () {
    this.id = uid++
    this.subs = []
  }

  addSub (sub: Watcher) {
    this.subs.push(sub)
  }

  removeSub (sub: Watcher) {
    remove(this.subs, sub)
  }

  depend () {
    if (Dep.target) {
      Dep.target.addDep(this)
    }
  }

  notify () {
    // stabilize the subscriber list first
    const subs = this.subs.slice()
    for (let i = 0, l = subs.length; i < l; i++) {
      subs[i].update()
    }
  }
}

Dep 就是一個 Watcher 所對應的數(shù)據(jù)依賴,在這個對象中也存有一個 subs 數(shù)組,用來保存和這個依賴有關的 Watcher。其成員函數(shù)最主要的是 depend 和 notify ,前者用來設置某個 Watcher 的依賴,后者則用來通知與這個依賴相關的 Watcher 來運行其回調函數(shù)。

我們知道,Dom 上通過指令或者雙大括號綁定的數(shù)據(jù),會為數(shù)據(jù)進行添加觀察者watcher,當實例化Watcher的時候 會觸發(fā)屬性的getter方法,此時會調用dep.depend()。我們看一下depend方法:

depend () {
  if (Dep.target) {
    Dep.target.addDep(this)
  }
}

Dep.target 是什么東西呢?其實在進行Watcher實例化的時候,會調用內部的get函數(shù),開始為他初始化

Watcher 觀察者

其中pushTarget 方法就是為Dep.target綁定此watcher實例,所以Dep.target.addDep(this)也就是執(zhí)行此實例中的addDep方法

addDep (dep: Dep) {
  ...
  dep.addSub(this)
}

這樣便為我們的dep實例添加了一個watcher實例。

接著當我們更新data的時候,會觸發(fā)他的set方法,執(zhí)行dep.notify()函數(shù):

notify () {
  // stabilize the subscriber list first
  const subs = this.subs.slice()
  for (let i = 0, l = subs.length; i < l; i++) {
    subs[i].update()
  }
}

這里也就是遍歷dep中收集到的watcher實例,進行update()。也就是進行數(shù)據(jù)更新操作。這也就是簡單的數(shù)據(jù)響應式,其實還需要注意的是: 當數(shù)據(jù)的getter觸發(fā)后,會收集依賴,但也不是所有的觸發(fā)方式都會收集依賴,只有通過watcher觸發(fā)的getter會收集依賴:if (Dep.target) { dep.depend() },而所謂的被收集的依賴就是當前watcher,DOM中的數(shù)據(jù)必須通過watcher來綁定,只通過watcher來讀取。

最后付一個函數(shù)timeline
的.png

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

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102995.html

相關文章

  • 源碼解析 —— Vue響應數(shù)據(jù)

    摘要:下面我們會向大家解釋清楚為什么這個這么重要,以及它和的響應式數(shù)據(jù)流有什么關系。源碼前面鋪墊這么多就是希望大家能理解接下來要講的響應式數(shù)據(jù)流。總結講到這里大家應該都能夠明白的響應式數(shù)據(jù)流是如何實現(xiàn)的。 Vue、React介紹 目前前端社區(qū)比較推崇的框架有Vue 和 React,公司內部許多端都自發(fā)的將原有的老技術方案(widget + jQuery)遷移到 Vue / React上了。我...

    LuDongWei 評論0 收藏0
  • vue.js響應原理解析與實現(xiàn)

    摘要:今天,就我們就來一步步解析響應式的原理,并且來實現(xiàn)一個簡單的。當然,這個也只是一個簡單的,來說明響應式的原理,真實的源碼會更加復雜,因為加了很多其他邏輯。接下來我可能會將其與聯(lián)系起來,實現(xiàn)和語法。 從很久之前就已經接觸過了angularjs了,當時就已經了解到,angularjs是通過臟檢查來實現(xiàn)數(shù)據(jù)監(jiān)測以及頁面更新渲染。之后,再接觸了vue.js,當時也一度很好奇vue.js是如何監(jiān)...

    Shihira 評論0 收藏0
  • 深入淺出Vue響應原理

    摘要:總結最后我們依照下圖參考深入淺出,再來回顧下整個過程在后,會調用函數(shù)進行初始化,也就是過程,在這個過程通過轉換成了的形式,來對數(shù)據(jù)追蹤變化,當被設置的對象被讀取的時候會執(zhí)行函數(shù),而在當被賦值的時候會執(zhí)行函數(shù)。 前言 Vue 最獨特的特性之一,是其非侵入性的響應式系統(tǒng)。數(shù)據(jù)模型僅僅是普通的 JavaScript 對象。而當你修改它們時,視圖會進行更新。這使得狀態(tài)管理非常簡單直接,不過理解...

    yiliang 評論0 收藏0
  • Vue 進階系列(一)之響應原理及實現(xiàn)

    摘要:進階系列一之響應式原理及實現(xiàn)進階系列二之插件原理及實現(xiàn)進階系列三之函數(shù)原理及實現(xiàn)什么是響應式表示一個狀態(tài)改變之后,如何動態(tài)改變整個系統(tǒng),在實際項目應用場景中即數(shù)據(jù)如何動態(tài)改變。描述符必須是這兩種形式之一,但二者不能共存,不然會出現(xiàn)異常。 (關注福利,關注本公眾號回復[資料]領取優(yōu)質前端視頻,包括Vue、React、Node源碼和實戰(zhàn)、面試指導)showImg(https://githu...

    MonoLog 評論0 收藏0

發(fā)表評論

0條評論

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