vue中數組的雙向綁定和監聽


vue2中使用的是object.defineProperty()通過劫持對象的屬性數據的變化進行監聽綁定的,

但對數組的變化監聽不到,所以vue2對數組的原型對象進行了重寫:

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

實踐過程中發現:

'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'這些重寫過的方法使用時,vue2中數組數據有進行實時的更新,
使用下標方式(arr[0] = 'sss')、直接修改數組長度arr.length = 1這兩種方式雖然改變了原數組,但此時VUE檢測不到數組變化,也不會更新視圖;使用watch中的 deep: true 也無效。
解決方法:
this.arr[0] = 'sss' 改寫為 this.$set(this.arr, 0, 'sss')
this.arr.length = 1 改寫為 const temp = this.arr.length - 1;this.arr.splice(1, temp)


vu3 數組中沒有上述問題, 因為使用的是 proxy,數組變化都可以監聽得到。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM