如何在Vue中监听数组的变化

  介绍

今天就跟大家聊聊有关如何在Vue中监听数组的变化,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

遍历数组,而后对数组中的每个对象调用观察方法

//,上一篇中出现的未曾重写的代码,这一篇中不再重复   var  Observer =, function 观察者(值),{   时间=this.value 才能;价值;   this.dep 才能=,new 取决于();//才能,如果是数组,则遍历所有元素   如果才能(Array.isArray(值)),{   ,,,this.observeArray(价值);   ,,},{else    ,,,this.walk(价值);   ,,}   };   时间=Observer.prototype.observeArray  function  observeArray(项目),{//才能,遍历数组所有元素,对单个元素进行,getter, setter 绑定   for 才能;(var 小姐:=,0,,l =, items.length;,小姐:& lt;, l;,我+ +),{   ,,,观察(项目[我]);   ,,}   };

<强>现实的要求

实际实现中当然不会如上例那么简单,官方文档中对监听数组是这样描述的:

Vue包含一组观察数组的突变方法,所以它们也将会触发视图更新。这些方法如下:
push(),流行(),(),转变平移(),拼接(),(),反向()

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

当你直接设置一个项的索引时,例如:vm。项目[indexOfItem]=newValue
当你修改数组的长度时,例如:vm.items。长度=newLength
所以,要对数组本身的一些方法进行监听。

经常要用到的一个小函数

def,在整个Vue源码中反复出现,利用Object.defineProperty()在obj上定义属性关键(也又可能是修改已存在属性键):

function  def (obj,钥匙,,val,,可列举的),{   Object.defineProperty才能(obj,钥匙,,{   ,,,的值:,val,   ,,,//,转变为,boole 值,如果不传参,转为,假的   ,,,可列举的:,! !可列举的,   ,,,可写:,真的,   ,,,可配置:真实   ,,});   }

<>强给对象添加一组方法

给对象添加一组方法,如果所在环境支持原型,就简单了,直接把对象的原型指向这一组方法就好了,如果不支持,则遍历这一组方法,依次添加到对象中,作为隐藏属性(即可列举的:假的,不能被在关键字找到):

var  hasProto =, & # 39; __proto__& # 39;,拷贝{};   var  augment =, hasProto  ?, protoAugment :, copyAugment;      function  protoAugment(目标,src), {   target.__proto__ 才能=,src;   }   function  copyAugment(目标,,src,键),{   ,,(var 小姐:=,0;,小姐:& lt;, keys.length;,我+ +),{   ,,,var  key =,键[我];   ,,,def(关键目标,,,,src[主要]);   ,,}   }

<>强先来一发简单的

var  arrayPush =, {};      (函数(方法){   var 才能;original =, Array.prototype[方法];   arrayPush才能[方法],=,()函数,{   ,,,//,却;能够指向可通过下面的测试看的出   ,,,console.log(这个);   ,,,return  original.apply(,,参数)   ,,};   })(& # 39;推动# 39;); var  testPush =, [];   时间=testPush.__proto__  arrayPush;//,通过输出,可以看出上面所述,却;能够指向的是,testPush//,[]   testPush.push (1);//,[1]   testPush.push (2);

<强>伪改写数组原型来监听数组的变化

如官方文档所言,所需监视的只有push(),流行(),(),转变平移(),拼接(),(),反向()7种方法,这7种方法有可分为两类:

1, push()、未(),拼接()这三种可能会给数组添加新元素的方法;

2,其余的不会新增元素的方法。

为了避免污染全局的数组,新建一个以数组。原型为原型的对象,而后在这个对象本身附加属性,再把这个新建的对象作为原型或者作为属性添加到观察者的价值中,来达到监视其变化的目的。

var  arrayProto =, Array.prototype;   var  arrayMethods =, Object.create (arrayProto);

接着就是遍历需要触发更新的几个方法,依次将其附加到arrayMethods上:

[& # 39;推动# 39;,,& # 39;流行# 39;,,& # 39;转变# 39;,,& # 39;平移# 39;,,& # 39;拼接# 39;,,& # 39;排序# 39;,,& # 39;反向# 39;].forEach(函数(方法),{//,才能获取原始的数组操作方法   var 才能;original =, arrayProto[方法];//,才能在,arrayMethods 上新建属性,方法,并为,method 指定值(函数)//才能,即改写,arrayMethods 上的同名数组方法   def才能(arrayMethods,方法,function  mutator (), {   ,,,var 参数,1美元=,参数;      ,,,var 小姐:=,arguments.length;   ,,,var  args =, new 数组(我);   ,,,//,将伪数组,arguments 转变为数组形式   ,,,//,为何不用,[].slice.call(参数)?   ,,,,(我),{   ,,,,,arg游戏[我],=,参数1美元[我];   ,,,}   ,,,var  result =, original.apply (,, args);   ,,,//,因,arrayMethods 是为了作为,Observer 中的,value 的原型或者直接作为属性,所以此处的,却,能够一般就是指向,Observer 中的,价值   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

如何在Vue中监听数组的变化