Vue怎么监听数组的变化

  介绍

这篇文章将为大家详细讲解有关Vue怎么监听数组的变化,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

在观察者的伪代码中我们模拟了如下代码:

class  Observer  {   ,构造函数(){//才能,响应式绑定数据通过方法   观察才能(this.data);   ,}   }      export  function  observe (数据),{   ,const  keys =,种(数据);   ,for  (let 小姐:=,0;,小姐:& lt;, keys.length;,我+ +),{//,才能将数据中我们定义的每个属性进行响应式绑定   defineReactive才能(obj,键[我]);   ,}   }      export  function  defineReactive  (), {   ,//÷?Object.defineProperty ,预备开始   }

今天我们就进一步了解观察者里还做了什么事。

<强>阵列的变化如何监听?

中数据的数据如果是一个数组怎么办?我们发现Object.defineProperty对数组进行响应式化是有缺陷的。

虽然我们可以监听到索引的改变。

function  defineReactive  (obj,钥匙,,val), {   Object.defineProperty才能(obj,钥匙,,{   ,,,可列举的:,真的,   可配置:,,,,真的,   ,,,得到:,(),=祝辞,{   ,,,,,console.log(& # 39;我被读了,我要不要做点什么好? & # 39;);   ,,,,,return  val;   ,,,},   ,,,:,newVal =祝辞,{   ,,,,,if  (val ===, newVal), {   ,,,,,,,返回;   ,,,,,}   ,,,,,val =, newVal;   ,,,,,console.log(“数据被改变了,我要渲染到页面上去!“);   ,,,}   })才能   }      let  data =, [1];//,对数组关键进行监听   defineReactive(数据,0,1);   console.log(数据[0]),,//,我被读了,我要不要做点什么好吗?   数据[0],=,2,,//,数据被改变了,我要渲染到页面上去!

但是defineProperty不能检测到数组长度的变化,准确的说是通过改变长度而增加的长度不能监测到。这种情况无法触发任何改变。

data.length =, 0;,//,控制台没有任何输出

而且监听数组所有索引的的代价也比较高,综合一些其他因素,Vue用了另一个方案来处理。

首先我们的观察需要改造一下,单独加一个数组的处理。

//,将数据中我们定义的每个属性进行响应式绑定   export  function  observe (数据),{   const 才能;keys =,种(数据);   for 才能;(let 小姐:=,0;,小姐:& lt;, keys.length;,我+ +),{   ,,,//,如果是数组   ,,,if  (Array.isArray(键[我])),{   ,,,,,observeArray(键[我]);   ,,,},{else    ,,,,,//,如果是对象   ,,,,,defineReactive (obj,键[我]);   ,,,}   ,,}   }//,数组的处理   export  function  observeArray  (), {//,才能…省略   }

那接下来我们就应该考虑下数组变化如何监听?

Vue中对这个数组问题的解决方案非常的简单粗暴,就是对能够改变数组的方法做了一些手脚。

我们知道,改变数组的方法有很多,举个例子比如说推方法吧.push存在Array.prototype上的,如果我们能
能拦截到原型上的推动方法,是不是就可以做一些事情呢?

<强> Object.defineProperty

对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。存取描述符是由getter-setter函数对描述的属性,也就是我们用来给对象做响应式绑定的.Object.defineProperty-MDN

虽然我们无法使用Object.defineProperty将数组进行响应式的处理,也就是getter-setter,但是还有其他的功能可以供我们使用。就是数据描述符,数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。

<强>价值

该属性对应的值。可以是任何有效的JavaScript值(数值,对象,函数等)。默认为定义。

<强>可写的

当且仅当该属性的可写为真时,价值才能被赋值运算符改变。默认为假的。

因此我们只要把原型上的方法,进行值的重新赋值。

如下代码,在重新赋值的过程中,我们可以获取到方法名和所有参数。

function  def  (obj,键),{   Object.defineProperty才能(obj,钥匙,,{   ,,,可写:,真的,   ,,,可列举的:,真的,   可配置:,,,,真的,   ,,,的值:,函数(…args), {   ,,,,,console.log(& # 39;关键# 39;,,键);   ,,,,,console.log (& # 39; args # 39;,, args),,   ,,,}   ,,});   }//,重写的数组方法   let  obj =, {   push(),才能{}   }//,数组方法的绑定   def (obj, & # 39;推动# 39;);      obj.push([1, 2], 7日,& # 39;你好! & # 39;);//,控制台输出,key 推动//,控制台输出,args [数组(2),7日,“喂!“)

Vue怎么监听数组的变化