首页 > 技术文章 > Vue变异数组

zhangxin123 2020-09-14 15:11 原文

我们知道在Vue中是通过Object.defineProperty()来实现数据的响应式,因为它可以很好的监听数据的修改(setter,getter)。

但是对于数组这一数据类型较为特殊,它只能监听到数组本身的变化,而对于数组内的元素变化是无法监听到的,也就是无法实现响应式:

由于 JavaScript 的限制, Vue 不能检测以下变动的数组:

当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength

对于想要实现数组的响应式,也就是在保持原数组不变的前提下延伸数组的方法,官方为我们提供了下面七个方法:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

至此,我们可以先思考下对于一个普通的方法,如何在保证不改变方法本身的前提下对它进行拓展呢?

看下面的例子:

function original() {
            console.log("abc");
}
const newA = original;
original = function () {
                console.log("def");
                newA();
}
original();
//expected output:>abc >def

我们设置了原始方法original,它输出的是abc,我们想在不改变这个基本逻辑的前提下,让它再输出def“:
  1.缓存原方法;

  2.重新定义原方法;

  3.在新定义的原方法中调用缓存方法;

在数组中,我们也可以按照这个思路来进行数组的功能扩展:

1.设置一个变量存储原数组的方法:

var oldArray = Array.prototype;
var newArray = Object.create(oldArray);

2.重新定义原数组方法:

//需要进行功能扩展的方法
var someMethods={
      'push',
      'pop',
      'shift',
      'unshift',
      'splice',
      'sort',
      'reverse'
}
//遍历重新定义原方法
someMethods.foreach((index,items)=>{
            let oldContent = oldArray[items];
            newArray = function (...args) {
                    let result = oldContent.apply(this,args);
                    return result;
             }
}

3.调用方法

let arr = [];
arr._proto_ = newArray;

 

推荐阅读