对数组的响应式处理

  • 在 src/observer/index.js 中
  • 将原生修改原数组的方法,进行重写,保留功能,并可以在数组改变时触发 notify 通知 watcher 更新视图
  • 并未处理 索引 和 length,虽然数组修改了,但是未触发 notify
  • 因为我们只处理了数组中的元素,而非属性(属性包含下标,length等等),不处理因为性能问题
  • 替代方案:通过 vm.arr.splice(0,1,100)
  • Vue.set()
  • this.$updateForce()

image.png

源码部分

if (Array.isArray(value)) {

  // hasProt用来判断 当前浏览器是否支持 对象原型 __proto__
  // 修补数组中的原型方法,如果数组发生变化调用 notify更新视图
  if (hasProto) {
    protoAugment(value, arrayMethods)
  } else {
    copyAugment(value, arrayMethods, arrayKeys)
  }

  // 遍历数组所有元素,是对象的元素会转化为响应式对象,而非所有属性!!!!
  // 下标和length是属性,无法通过 vm.msg[0]更新,因为性能问题
  // 可以使用 vm.msg.splice(0,1,100) 代替
  this.observeArray(value)
} 

else {
  // 遍历对象中的每个属性,转换成 setter/getter
  this.walk(value)
}
const arrayProto = Array.prototype

// 创建一个对象,对象原型指向 传入的参数 (此对象的原型指向Array.prototype)
export const arrayMethods = Object.create(arrayProto)

// 修改原数组元素的方法 (修改原数据会调用dep.notify,通知watcher去更新视图,但是数组原生方法不会,需要修补)
const methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]

mcgee0731
60 声望4 粉丝

不会做饭的程序猿不是一个好厨子