Vue知识回顾与总结【二】

Vue知识回顾与总结【二】

第二章 Vue如何实现数组的变化侦测

写在前面

       今天是一个特殊的日子,在此向所有逆行者致敬,向所有牺牲者致哀!!!

Vue数组的变化侦测为什么和对象不同?

       首先我们思考这样一个问题,为什么在Vue中数组的变化侦测和对象不同?因为我们可以通过Array原型的方式操作数据,所以Object的getter和setter方式就无法侦测到数组元素的变化。
       Array中可以改变数组的方法有以下7个:

  1. push 向数组尾部加入单个或多个元素
  2. pop 弹出数组尾部的最后一个元素
  3. shift弹出数组首部的第一个元素
  4. unshift向数组首部加入元素
  5. splice截切数组
  6. sort数组排序
  7. reverse简单的数组元素反转

Vue的办法:利用拦截器覆盖Array.prototype

       利用拦截器覆盖Aray.prototype,即重写Array的原型方法。当我们再Vue中调用上述7个方法时,其实是在调用Vue的拦截器方法。这样就可以在拦截器内部实现依赖管理的相关操作和逻辑。

Vue 数组中的依赖管理

       数组仍然是在getter上收集依赖,而依赖的触发则是放到拦截器中进行。数组和对象不同的地方在于依赖存放的位置不同,Vue把数组的依赖放在了Observer实例中其目的是保证拦截器和getter都能访问到依赖。这样就能通过ob.dep.notify()去通知依赖watcher数据发生了变化。

  1. 备注:ob:Observer实例;dep:Dep实例;watcher:Watcher实例

无法侦测的情况

       Array的变化侦测通过拦截原型的方法实现,因而有些操作数组的方法是无法实现变化侦测的,比如:

  1. 通过数据索引改变数组元素:如this.arr[1] = 111;
  2. 通过length改变数组的长度:如thia.arr.length = 10;
  • 上述两种方式我们在开发时应当尽量避免,除非操作的是非响应式数据。此外可以通过全局APIthis.$set()和this.$delete()解决问题1.

对_proto_的处理

       为了不污染全局Array.prototype,希望Observer中只针对需要侦测数据变化的数组使用_proto_来覆盖原型方法,但是_proto_属性在ES6之前不是所有浏览器都支持,针对不支持_proto_属性的浏览器采用比较“暴力”的方式,直接循环拦截器,将拦截器方法设置到数组身上来拦截Array.prototype上的原生方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mingyong.g

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值