最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

介紹

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

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

observer模塊在Vue項目中的代碼位置是src/core/observer,模塊共分為這幾個部分:

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

示意圖如下:

Observer

Observer類定義在src/core/observer/index.js中,先來看一下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ù)對象,在構(gòu)造函數(shù)中,會給value增加__ob__屬性,作為數(shù)據(jù)已經(jīng)被Observer觀察的標(biāo)志。如果value是數(shù)組,就使用observeArray遍歷value,對value中每一個元素調(diào)用observe分別進(jìn)行觀察。如果value是對象,則使用walk遍歷value上每個key,對每個key調(diào)用defineReactive來獲得該key的set/get控制權(quán)。

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

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

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

Dep

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

Dep提供了幾個接口:

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

Watcher

Watcher是用來訂閱數(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表示組件實例,expOrFn表示要訂閱的數(shù)據(jù)字段(字符串表示,例如a.b.c)或是一個要執(zhí)行的函數(shù),cb表示watcher運行后的回調(diào)函數(shù),options是選項對象,包含deep、user、lazy等配置。

watcher實例上有這些方法:

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

Array methods

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

在Vue的官方文檔中對這個也有說明:http://cn.vuejs.org/v2/guide/list.html#變異方法

總結(jié)

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

相關(guān)文章

  • vue3的defineExpose宏函數(shù)是如何暴露方法給父組件使用

    vue3的defineExpose宏函數(shù)是如何暴露方法給父組件使用

    當(dāng)子組件使用setup后,父組件就不能像vue2那樣直接就可以訪問子組件內(nèi)的屬性和方法,這個時候就需要在子組件內(nèi)使用defineExpose宏函數(shù)來指定想要暴露出去的屬性和方法,本文介紹vue3的defineExpose宏函數(shù)是如何暴露方法給父組件使用,需要的朋友可以參考下
    2024-05-05
  • 淺談vue方法內(nèi)的方法使用this的問題

    淺談vue方法內(nèi)的方法使用this的問題

    今天小編就為大家分享一篇淺談vue方法內(nèi)的方法使用this的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Vue項目中ESLint配置超全指南(VScode)

    Vue項目中ESLint配置超全指南(VScode)

    ESLint是一個代碼檢查工具,用來檢查你的代碼是否符合指定的規(guī)范,下面這篇文章主要給大家介紹了關(guān)于Vue項目中ESLint配置(VScode)的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • vue-element內(nèi)table插入超鏈接a標(biāo)簽的使用

    vue-element內(nèi)table插入超鏈接a標(biāo)簽的使用

    在Vue Element的table組件中插入超鏈接,可以使用<el-link>標(biāo)簽替代傳統(tǒng)的<a>標(biāo)簽,實現(xiàn)更加整潔的UI設(shè)計,具體操作是替換原有的<span>標(biāo)簽,直接使用<el-link>進(jìn)行超鏈接的插入,使得鏈接樣式與Element UI保持一致
    2024-09-09
  • 解決父組件將子組件作為彈窗調(diào)用只執(zhí)行一次created的問題

    解決父組件將子組件作為彈窗調(diào)用只執(zhí)行一次created的問題

    這篇文章主要介紹了解決父組件將子組件作為彈窗調(diào)用只執(zhí)行一次created的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • vue使用路由router-view的詳細(xì)代碼

    vue使用路由router-view的詳細(xì)代碼

    這篇文章主要介紹了vue使用路由router-view的相關(guān)知識,其原理就是采用?SPA(single-page-application)?模式,就是只有一個?Web?頁面的應(yīng)用,通過?router?來控制頁面的刷新和迭代,感興趣的朋友一起看看吧
    2023-12-12
  • Vue3使用TypeIt實現(xiàn)文字打字機(jī)效果的代碼示例

    Vue3使用TypeIt實現(xiàn)文字打字機(jī)效果的代碼示例

    在現(xiàn)代網(wǎng)頁設(shè)計中,文字打字機(jī)效果是一種非常流行的動畫效果,能夠吸引用戶的注意力并提升用戶體驗,本文將介紹如何在 Vue 3 中使用 TypeIt 庫實現(xiàn)文字打字機(jī)效果,并分享一些實用的技巧和示例,需要的朋友可以參考下
    2025-01-01
  • vue項目使用websocket連接問題及解決

    vue項目使用websocket連接問題及解決

    這篇文章主要介紹了vue項目使用websocket連接問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 深入淺析Vue中的Prop

    深入淺析Vue中的Prop

    Prop的基本用法很簡單,只需要在子組件的Vue實例中定義該屬性并把值設(shè)為目標(biāo)屬性的數(shù)組即可。這篇文章主要介紹了Vue中的Prop ,需要的朋友可以參考下
    2018-06-06
  • Vue中this.$refs獲取為undefined的原因和解決辦法(this.$refs.屬性為undefined原因)

    Vue中this.$refs獲取為undefined的原因和解決辦法(this.$refs.屬性為undefined原因

    在Vue項目開發(fā)中,使用this.$refs訪問組件或DOM元素的引用時,可能會遇到獲取為undefined的情況,這篇文章主要介紹了Vue中this.$refs獲取為undefined的原因和解決辦法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-11-11

最新評論

滨州市| 柳林县| 县级市| 武鸣县| 桂阳县| 澄迈县| 盖州市| 天峻县| 巫溪县| 湘乡市| 武乡县| 原阳县| 寿阳县| 宜阳县| 青海省| 邵武市| SHOW| 安陆市| 兴隆县| 汝南县| 深水埗区| 兴仁县| 报价| 洞口县| 平安县| 扎兰屯市| 柯坪县| 杨浦区| 大新县| 陆良县| 乌鲁木齐县| 绍兴市| 保康县| 乐昌市| 中山市| 昭平县| 平塘县| 饶阳县| 汪清县| 通辽市| 佛学|