国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

香港云服务器
服務器之家 - 編程語言 - JavaScript - vue中是怎樣監聽數組變化的

vue中是怎樣監聽數組變化的

2021-11-05 18:59ming1025 JavaScript

這篇文章主要介紹了vue中是怎樣監聽數組變化的,幫助大家更好的理解和學習vue,感興趣的朋友可以了解下

我們知道通過Object.defineProperty()劫持數組為其設置getter和setter后,調用的數組的push、splice、pop等方法改變數組元素時并不會觸發數組的setter,這就會造成使用上述方法改變數組后,頁面上并不能及時體現這些變化,也就是數組數據變化不是響應式的(對上述不了解的可以參考這篇文章)。但實際用vue開發時,對于響應式數組,使用push、splice、pop等方法改變數組時,頁面會及時體現這種變化,那么vue中是如何實現的呢?

通過vue源碼可以看出,vue重寫了數組的push、splice、pop等方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// src/core/observer/array.js
 
// 獲取數組的原型Array.prototype,上面有我們常用的數組方法
const arrayProto = Array.prototype
// 創建一個空對象arrayMethods,并將arrayMethods的原型指向Array.prototype
export const arrayMethods = Object.create(arrayProto)
 
// 列出需要重寫的數組方法名
const methodsToPatch = [
 'push',
 'pop',
 'shift',
 'unshift',
 'splice',
 'sort',
 'reverse'
]
// 遍歷上述數組方法名,依次將上述重寫后的數組方法添加到arrayMethods對象上
methodsToPatch.forEach(function (method) {
 // 保存一份當前的方法名對應的數組原始方法
 const original = arrayProto[method]
 // 將重寫后的方法定義到arrayMethods對象上,function mutator() {}就是重寫后的方法
 def(arrayMethods, method, function mutator (...args) {
  // 調用數組原始方法,并傳入參數args,并將執行結果賦給result
  const result = original.apply(this, args)
  // 當數組調用重寫后的方法時,this指向該數組,當該數組為響應式時,就可以獲取到其__ob__屬性
  const ob = this.__ob__
  let inserted
  switch (method) {
   case 'push':
   case 'unshift':
    inserted = args
    break
   case 'splice':
    inserted = args.slice(2)
    break
  }
  if (inserted) ob.observeArray(inserted)
  // 將當前數組的變更通知給其訂閱者
  ob.dep.notify()
  // 最后返回執行結果result
  return result
 })
})

從上面可以看出array.js中重寫了數組的push、pop、shift、unshift、splice、sort、reverse七種方法,重寫方法在實現時除了將數組方法名對應的原始方法調用一遍并將執行結果返回外,還通過執行ob.dep.notify()將當前數組的變更通知給其訂閱者,這樣當使用重寫后方法改變數組后,數組訂閱者會將這邊變化更新到頁面中。

重寫完數組的上述7種方法外,我們還需要將這些重寫的方法應用到數組上,因此在Observer構造函數中,可以看到在監聽數據時會判斷數據類型是否為數組。當為數組時,如果瀏覽器支持__proto__,則直接將當前數據的原型__proto__指向重寫后的數組方法對象arrayMethods,如果瀏覽器不支持__proto__,則直接將arrayMethods上重寫的方法直接定義到當前數據對象上;當數據類型為非數組時,繼續遞歸執行數據的監聽。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// src/core/observer/index.js
export class Observer {
 ...
 constructor (value: any) {
  this.value = value
  this.dep = new Dep()
  this.vmCount = 0
  def(value, '__ob__', this)
  if (Array.isArray(value)) {
   if (hasProto) {
    protoAugment(value, arrayMethods)
   } else {
    copyAugment(value, arrayMethods, arrayKeys)
   }
   this.observeArray(value)
  } else {
   this.walk(value)
  }
 }
 ...
}
function protoAugment (target, src: Object) {
 /* eslint-disable no-proto */
 target.__proto__ = src
 /* eslint-enable no-proto */
}
function copyAugment (target: Object, src: Object, keys: Array<string>) {
 for (let i = 0, l = keys.length; i < l; i++) {
  const key = keys[i]
  def(target, key, src[key])
 }
}

經過上述處理后,對于數組,當我們調用其方法處理數組時會按照如下原型鏈來獲取數組方法:

vue中是怎樣監聽數組變化的

對于響應式數組,當瀏覽器支持__proto__屬性時,使用push等方法時先從其原型arrayMethods上尋找push方法,也就是重寫后的方法,處理之后數組的變化會通知到其訂閱者,更新頁面,當在arrayMethods上查詢不到時會向上在Array.prototype上查詢;當瀏覽器不支持__proto__屬性時,使用push等方法時會先從數組自身上查詢,如果查詢不到會向上再Array.prototype上查詢。

對于非響應式數組,當使用push等方法時會直接從Array.prototype上查詢。

值得一提的是源碼中通過判斷瀏覽器是否支持__proto__來分別使用protoAugment和copyAugment 方法將重寫后的數組方法應用到數組中,這是因為對于IE10及以下的IE瀏覽器是不支持__proto__屬性的:

上述截圖參考于Vue源碼解析五——數據響應系統

結論:

在將數組處理成響應式數據后,如果使用數組原始方法改變數組時,數組值會發生變化,但是并不會觸發數組的setter來通知所有依賴該數組的地方進行更新,為此,vue通過重寫數組的某些方法來監聽數組變化,重寫后的方法中會手動觸發通知該數組的所有依賴進行更新。

如果我的內容能對你有所幫助,我就很開心啦!

以上就是vue中是怎樣監聽數組變化的的詳細內容,更多關于vue 監聽數組變化的資料請關注服務器之家其它相關文章!

原文鏈接:https://www.cnblogs.com/ming1025/p/13082822.html

延伸 · 閱讀

精彩推薦
912
主站蜘蛛池模板: 欧美午夜影院 | 国产精品久久久久久久久久久新郎 | 一区二区三区高清不卡 | 在线播放一区二区三区 | 亚洲国产精品yw在线观看 | 欧美日韩综合在线 | 91精品国产一区二区三区香蕉 | 国产精品a久久久久 | 精品美女一区 | 国产日产久久高清欧美一区 | 亚洲精品乱码久久久久久按摩观 | 亚洲在线一区二区 | 欧美精品一区二区三区四区在线 | 国产一区二区免费 | 日韩在线观看 | 大胆一区 | 自拍小电影 | 中文字幕在线精品 | 黄色在线免费 | 国产精品一区二区三区不卡 | 欧美精品欧美精品系列 | 国产一级在线 | 国产日韩一区二区 | 精品精品| 黄色一级电影在线观看 | 久久丝袜诱惑 | 毛片免费的| 成人午夜精品 | 成人国产精品久久久 | 日韩成人在线播放 | 毛片一级网站 | 综合久久网 | 亚洲国产精品尤物yw在线观看 | 亚洲大片av | 国内av网站 | 日本视频二区 | 国产精品久久久久久中文字 | 成人精品一区二区三区 | 色中色av | 2024国产精品 | 亚洲视频1|