今天就跟大家聊聊有关使用vue如何监听数组变化,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

我们知道通过Object.defineProperty()劫持数组为其设置getter和setter后,调用的数组的push、splice、pop等方法改变数组元素时并不会触发数组的setter,这就会造成使用上述方法改变数组后,页面上并不能及时体现这些变化,也就是数组数据变化不是响应式的(对上述不了解的可以参考这篇文章)。但实际用vue开发时,对于响应式数组,使用push、splice、pop等方法改变数组时,页面会及时体现这种变化,那么vue中是如何实现的呢?
通过vue源码可以看出,vue重写了数组的push、splice、pop等方法。
// 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
})
})