vue中数组的双向绑定和监听

vue2中使用的是object.defineProperty()通过劫持对象的属性数据的变化进行监听绑定的,

但对数组的变化监听不到,所以vue2对数组的原型对象进行了重写:

复制代码
// 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
  })
})
复制代码

实践过程中发现:

'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'这些重写过的方法使用时,vue2中数组数据有进行实时的更新,
使用下标方式(arr[0] = 'sss')、直接修改数组长度arr.length = 1这两种方式虽然改变了原数组,但此时VUE检测不到数组变化,也不会更新视图;使用watch中的 deep: true 也无效。
解决方法:
this.arr[0] = 'sss' 改写为 this.$set(this.arr, 0, 'sss')
this.arr.length = 1 改写为 const temp = this.arr.length - 1;this.arr.splice(1, temp)


vu3 数组中没有上述问题, 因为使用的是 proxy,数组变化都可以监听得到。
posted @   梦想行动家  阅读(1756)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示