vue如何监听数组的变化
阅读原文时间:2023年07月08日阅读:2

export function def (obj: Object, key: string, val: any, enumerable?: boolean) {
Object.defineProperty(obj, key, {
value: val,
enumerable: !!enumerable,
writable: true,
configurable: true
})
}
observeArray (items: Array) {
  for (let i = 0, l = items.length; i < l; i++) {
    observe(items[i])
  }
}

源码:import { def } from '../util/index'

_const arrayProto = Array.prototype
// 创建arrayMehtods对象,指向Array的原型
export const arrayMethods = Object.create(arrayProto)

const methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
]

/**
* Intercept mutating methods and emit events
*/
methodsToPatch.forEach(function (method) {
// cache original method
const original = arrayProto[method]
 // 监听数组原型上的方法
def(arrayMethods, method, function mutator (…args) {
const result = original.apply(this, args)
const ob = this.__ob__
let inserted
  // 如果遇到push,unshift,splice方法,这些新增元素的方法,Object.defineProperty不会自动检测到,需要重新使用数据劫持进行检测。
switch (method) {
case 'push':
case 'unshift':
inserted = args
break
case 'splice':
inserted = args.slice(2)
break
}
  // 如果发生了新增,就重新进行数据劫持
if (inserted) ob.observeArray(inserted)
// notify change
  //通知dom进行更新

ob.dep.notify()  
return result  

})
})_

1.重写了操作数组的方法,在数组的push,unshift,splice改变数组长度的方法中,通过Object.definePeoperty劫持新增的数组的数据,实现双向数据绑定。同时更新demo