vue响应式讲解-array
前端小菜-贺俊兰 2019-09-05 VUE
- array类型的响应式跟object类型一样,获取数据时收集依赖,数据变化时通知依赖更新
*这里vue分成两种数据类型的响应式,是因为array类型的数据无法使用object.defineProperty,这个api只针对object类型的,所以array类型的响应式转化需要额外的操作。
*虽然说Array类型无法使用Object.defineProperty,但是Array数据还是存在于某个对象中,所以还是可以触发Array数据的getter,总结一句话:Array型数据还是在getter中收集依赖。
1
2
3
2
3
- 制作数组方法拦截器(arrayMethods),模仿原生数组方法(7种操作原有数组的api)
*思路:而setter,array类型无法使用,这里vue模拟了一个拦截器,通过模拟原生数组的方法,来解决这个问题,当用户操作数组时,通常通过数组方法来改变原数组。操作原数组的方法有7种,通过复制并拦截这几种方法,在调用的过程种更新依赖,就可以达到更新setter的目的。
*方法:通过Object.create方法创造出空对象arrayMethods继承Array.prototype,通过监听arrayMethods的数组方法来达到更新的目的
1
2
3
2
3
使用并挂载拦截器 vue为了每个数据和拦截器一一对应,就把arrayMethods挂载到array数据的__proto__,并做了兼容处理,如果浏览器不兼容,数组方法直接当作array数据的属性进行遍历添加。
依赖收集getter 依赖收集这里,原理就跟我们的Object类型的一样了,也是通过getter调用dep.depend()来进行。
依赖更新setter 而更新依赖则是在封装拦截器的地方通过dep.notify()进行更新。
深度监测(多维度数据类型的监听封装,for循环添加)
新增数组元素的侦测和封装(push,unshift,splice) 当数据通过push等数组方法被调用时,会新增数组元素,此时的新增元素不是响应式的,需要重新执行ob.observeArray把新元素转化为响应式元素。
缺点: 无法侦测到通过下标修改数组属性值的方式,例如:arr[0].length = 2; arr[0] = 2。同样可以通过vue.set和vue.delete解决。