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,数组变化都可以监听得到。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!