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

Vue.js原理分析之observer模塊詳解

 更新時(shí)間:2017年02月17日 09:05:29   作者:JoeRay61  
這篇文章主要介紹了Vue.js中observer模塊的相關(guān)資料,文中通過(guò)原理分析介紹還是相對(duì)的詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。

介紹

observer是Vue核心中最重要的一個(gè)模塊(個(gè)人認(rèn)為),能夠?qū)崿F(xiàn)視圖與數(shù)據(jù)的響應(yīng)式更新,底層全憑observer的支持。

注意:本文是針對(duì)Vue@2.1.8進(jìn)行分析

observer模塊在Vue項(xiàng)目中的代碼位置是src/core/observer,模塊共分為這幾個(gè)部分:

  1. Observer: 數(shù)據(jù)的觀察者,讓數(shù)據(jù)對(duì)象的讀寫(xiě)操作都處于自己的監(jiān)管之下
  2. Watcher: 數(shù)據(jù)的訂閱者,數(shù)據(jù)的變化會(huì)通知到Watcher,然后由Watcher進(jìn)行相應(yīng)的操作,例如更新視圖
  3. Dep: Observer與Watcher的紐帶,當(dāng)數(shù)據(jù)變化時(shí),會(huì)被Observer觀察到,然后由Dep通知到Watcher

示意圖如下:

Observer

Observer類(lèi)定義在src/core/observer/index.js中,先來(lái)看一下Observer的構(gòu)造函數(shù)

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)
 }
}

value是需要被觀察的數(shù)據(jù)對(duì)象,在構(gòu)造函數(shù)中,會(huì)給value增加__ob__屬性,作為數(shù)據(jù)已經(jīng)被Observer觀察的標(biāo)志。如果value是數(shù)組,就使用observeArray遍歷value,對(duì)value中每一個(gè)元素調(diào)用observe分別進(jìn)行觀察。如果value是對(duì)象,則使用walk遍歷value上每個(gè)key,對(duì)每個(gè)key調(diào)用defineReactive來(lái)獲得該key的set/get控制權(quán)。

解釋下上面用到的幾個(gè)函數(shù)的功能:

  • observeArray: 遍歷數(shù)組,對(duì)數(shù)組的每個(gè)元素調(diào)用observe
  • observe: 檢查對(duì)象上是否有__ob__屬性,如果存在,則表明該對(duì)象已經(jīng)處于Observer的觀察中,如果不存在,則new Observer來(lái)觀察對(duì)象(其實(shí)還有一些判斷邏輯,為了便于理解就不贅述了)
  • walk: 遍歷對(duì)象的每個(gè)key,對(duì)對(duì)象上每個(gè)key的數(shù)據(jù)調(diào)用defineReactive
  • defineReactive: 通過(guò)Object.defineProperty設(shè)置對(duì)象的key屬性,使得能夠捕獲到該屬性值的set/get動(dòng)作。一般是由Watcher的實(shí)例對(duì)象進(jìn)行g(shù)et操作,此時(shí)Watcher的實(shí)例對(duì)象將被自動(dòng)添加到Dep實(shí)例的依賴(lài)數(shù)組中,在外部操作觸發(fā)了set時(shí),將通過(guò)Dep實(shí)例的notify來(lái)通知所有依賴(lài)的watcher進(jìn)行更新。

如果不太理解上面的文字描述可以看一下圖:

Dep

Dep是Observer與Watcher之間的紐帶,也可以認(rèn)為Dep是服務(wù)于Observer的訂閱系統(tǒng)。Watcher訂閱某個(gè)Observer的Dep,當(dāng)Observer觀察的數(shù)據(jù)發(fā)生變化時(shí),通過(guò)Dep通知各個(gè)已經(jīng)訂閱的Watcher。

Dep提供了幾個(gè)接口:

  • addSub: 接收的參數(shù)為Watcher實(shí)例,并把Watcher實(shí)例存入記錄依賴(lài)的數(shù)組中
  • removeSub: 與addSub對(duì)應(yīng),作用是將Watcher實(shí)例從記錄依賴(lài)的數(shù)組中移除
  • depend: Dep.target上存放這當(dāng)前需要操作的Watcher實(shí)例,調(diào)用depend會(huì)調(diào)用該Watcher實(shí)例的addDep方法,addDep的功能可以看下面對(duì)Watcher的介紹
  • notify: 通知依賴(lài)數(shù)組中所有的watcher進(jìn)行更新操作

Watcher

Watcher是用來(lái)訂閱數(shù)據(jù)的變化的并執(zhí)行相應(yīng)操作(例如更新視圖)的。Watcher的構(gòu)造器函數(shù)定義如下:

constructor (vm, expOrFn, cb, options) {
 this.vm = vm
 vm._watchers.push(this)
 // options
 if (options) {
 this.deep = !!options.deep
 this.user = !!options.user
 this.lazy = !!options.lazy
 this.sync = !!options.sync
 } else {
 this.deep = this.user = this.lazy = this.sync = false
 }
 this.cb = cb
 this.id = ++uid // uid for batching
 this.active = true
 this.dirty = this.lazy // for lazy watchers
 this.deps = []
 this.newDeps = []
 this.depIds = new Set()
 this.newDepIds = new Set()
 this.expression = process.env.NODE_ENV !== 'production'
 ? expOrFn.toString()
 : ''
 if (typeof expOrFn === 'function') {
 this.getter = expOrFn
 } else {
 this.getter = parsePath(expOrFn)
 if (!this.getter) {
 this.getter = function () {}
 process.env.NODE_ENV !== 'production' && warn(
 `Failed watching path: "${expOrFn}" ` +
 'Watcher only accepts simple dot-delimited paths. ' +
 'For full control, use a function instead.',
 vm
 )
 }
 }
 this.value = this.lazy
 ? undefined
 : this.get()
}

參數(shù)中,vm表示組件實(shí)例,expOrFn表示要訂閱的數(shù)據(jù)字段(字符串表示,例如a.b.c)或是一個(gè)要執(zhí)行的函數(shù),cb表示watcher運(yùn)行后的回調(diào)函數(shù),options是選項(xiàng)對(duì)象,包含deep、user、lazy等配置。

watcher實(shí)例上有這些方法:

  • get: 將Dep.target設(shè)置為當(dāng)前watcher實(shí)例,在內(nèi)部調(diào)用this.getter,如果此時(shí)某個(gè)被Observer觀察的數(shù)據(jù)對(duì)象被取值了,那么當(dāng)前watcher實(shí)例將會(huì)自動(dòng)訂閱數(shù)據(jù)對(duì)象的Dep實(shí)例
  • addDep: 接收參數(shù)dep(Dep實(shí)例),讓當(dāng)前watcher訂閱dep
  • cleanupDeps: 清除newDepIds和newDep上記錄的對(duì)dep的訂閱信息
  • update: 立刻運(yùn)行watcher或者將watcher加入隊(duì)列中等待統(tǒng)一flush
  • run: 運(yùn)行watcher,調(diào)用this.get()求值,然后觸發(fā)回調(diào)
  • evaluate: 調(diào)用this.get()求值
  • depend: 遍歷this.deps,讓當(dāng)前watcher實(shí)例訂閱所有dep
  • teardown: 去除當(dāng)前watcher實(shí)例所有的訂閱

Array methods

在src/core/observer/array.js中,Vue框架對(duì)數(shù)組的push、pop、shift、unshift、sort、splice、reverse方法進(jìn)行了改造,在調(diào)用數(shù)組的這些方法時(shí),自動(dòng)觸發(fā)dep.notify(),解決了調(diào)用這些函數(shù)改變數(shù)組后無(wú)法觸發(fā)更新的問(wèn)題。

在Vue的官方文檔中對(duì)這個(gè)也有說(shuō)明:http://cn.vuejs.org/v2/guide/list.html#變異方法

總結(jié)

以上就是這篇文中的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。

相關(guān)文章

  • vue中el-autocomplete與el-select的異同

    vue中el-autocomplete與el-select的異同

    本文主要介紹了vue中el-autocomplete與el-select的異同,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • vue滑動(dòng)解鎖組件使用方法詳解

    vue滑動(dòng)解鎖組件使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了vue滑動(dòng)解鎖組件的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Vue判斷字符串(或數(shù)組)中是否包含某個(gè)元素的多種方法

    Vue判斷字符串(或數(shù)組)中是否包含某個(gè)元素的多種方法

    在我們前端日常開(kāi)發(fā)中經(jīng)常會(huì)遇到判斷一個(gè)字符串中是否包含某個(gè)元素的需求,下面這篇文章主要給大家介紹了關(guān)于Vue判斷字符串(或數(shù)組)中是否包含某個(gè)元素的多種方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • 詳解Vue中watch對(duì)象內(nèi)屬性的方法

    詳解Vue中watch對(duì)象內(nèi)屬性的方法

    這篇文章主要介紹了詳解Vue中watch對(duì)象內(nèi)屬性的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • vue3組件中v-model的使用以及深入講解

    vue3組件中v-model的使用以及深入講解

    在vue2中v-model使用的還是挺多的,不過(guò)這個(gè)指令一般是用在了輸入框中,并且這個(gè)指令其實(shí)就是個(gè)語(yǔ)法糖,下面這篇文章主要給大家介紹了關(guān)于vue3組件中v-model的使用以及深入講解的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • Vue實(shí)現(xiàn)可復(fù)用輪播組件的方法

    Vue實(shí)現(xiàn)可復(fù)用輪播組件的方法

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)可復(fù)用輪播組件的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 一起來(lái)學(xué)習(xí)Vue的組件間通信方式

    一起來(lái)學(xué)習(xí)Vue的組件間通信方式

    這篇文章主要為大家詳細(xì)介紹了Vue的組件間通信方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • 在vue中使用G2圖表的示例代碼

    在vue中使用G2圖表的示例代碼

    這篇文章主要介紹了在vue中使用G2圖表的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • 使用Vue開(kāi)發(fā)自己的Chrome擴(kuò)展程序過(guò)程詳解

    使用Vue開(kāi)發(fā)自己的Chrome擴(kuò)展程序過(guò)程詳解

    這篇文章主要介紹了使用Vue開(kāi)發(fā)自己的Chrome擴(kuò)展程序過(guò)程詳解,瀏覽器擴(kuò)展程序是可以修改和增強(qiáng) Web 瀏覽器功能的小程序。它們可用于各種任務(wù),例如阻止廣告,管理密碼,組織標(biāo)簽,改變網(wǎng)頁(yè)的外觀和行為等等。,需要的朋友可以參考下
    2019-06-06
  • vue在body和query中如何向后端傳參

    vue在body和query中如何向后端傳參

    這篇文章主要介紹了vue在body和query中如何向后端傳參,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09

最新評(píng)論