vue原理:vue中是如何监听数组变化?
发布日期:2021-05-07 10:00:17 浏览次数:18 分类:精选文章

本文共 1339 字,大约阅读时间需要 4 分钟。

我们知道通过Object.defineProperty()劫持数组为其设置getter和setter后,调用的数组的push、splice、pop等方法改变数组元素时并不会触发数组的setter,这就会造成使用上述方法改变数组后,页面上并不能及时体现这些变化,也就是数组数据变化不是响应式的(对上述不了解的可以参考这篇文章)。

但实际用vue开发时,对于响应式数组,使用push、splice、pop等方法改变数组时,页面会及时体现这种变化,那么vue中是如何实现的呢?

答案是 vue 重写了数组的push、splice、pop等方法。

// src/core/observer/array.js// 获取数组的原型Array.prototype,上面有我们常用的数组方法const arrayProto = Array.prototype// 创建一个空对象arrayMethods,并将arrayMethods的原型指向Array.prototypeexport 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  })})
上一篇:js:虚拟dom与diff算法
下一篇:vue3:Composition API

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年03月21日 11时26分57秒