V2中通过数组下标改变数组元素以及改变数组长度监听不到的原因

发布时间:2024年01月08日

v2中是通过Object.defineProperty()监听对象属性,实现响应式系统

一、数组

1、针对数组,存在两种不能监听的情况:

(1) 直接通过下标修改数组元素: arr[index]=value

(2)直接修改数组长度 : arr.length=newLength

针对以上两种不能监听的情况:先说解决方案如下:

通过下标修改数组元素,以下三种解决方案:

(1) Vue.set(arr,index,newValue)

(2) vm.$set(arr,index,newValue)

(3)arr.splice(index,1,newValue) //先删除再添加

直接修改数组长度监听不到,解决方案:

arr.splice(newLength) //截取数组

2、vue如何监听数组的变化?

vue中劫持了数组的7个方法:push,pop,shift,unshift,reverse,sort,splice,在vue内部重写了数组的原型;

重点3:vue2通过数组下标和长度修改数组为什么检测不到呢?

(1)第一点:首先V2中的Object.defineProperty()----->可以检测到:通过数组下标改变数组元素(对于数组其实和obj是一样的,数组的下标就相当于对象的属性);通过下图可以看到,通过下标修改数组元素时,可以检测到变化;

在这里插入图片描述

(2)Object.defineProperty()是可以对数组实现监听操作的,但是vue并没有实现这个这个功能,因为数组长度不定而且数据可能会很多,如果对每一个数据都实现监听,性能代价太大;但是也要注意:数组中的元素是应用类型时是会被监听到的;

在这里插入图片描述

二、对象

1、不能监听的情况:属性的新增和删除

(1) obj.newKey=newValue

(2) delete obj.key

针对以上不能监听的情况:处理方法如下

----新增时:

(1) Vue.set(obj,newKey,newValue)

(2) vm.$set(obj,newKey,newValue)

(3) obj=Object.assign({},obj,{newKey1:newValue1,newKey2:newValue2})

//使用Object.assign方法合并对象,并返回一个新对象

----删除时

(1) Vue.delete(obj,key)

(2) vm.$delete(obj,key)

三、 v3的响应式数据原理:

vue 3是通过proxy直接代理整个对象来实现的,而不是像Object.defineProperty针对某个属性。

所以,只需做一层代理就可以监听同级结构下的所有属性变化,包括新增属性和删除属性

四、关于vue监听的一些问题

(1)对象的监听

vue通过object.defineProperty将对象的key转化成getter/setter的形式来追踪变化,但是这种追踪方式只能追踪到数据的修改;

对象的属性的删除和增加,这种形式追踪不到(因为追踪对象属性变化在数据初始化时已经完成,当我们手动添加或删除属性时,需要手动进行observe(检测),即需要重新遍历对象,再对新增属性再使用defineproperty进行劫持)。

为此vue提供可$set 和$delete两种API来配合使用,解决监听不到属性新增删除问题。

*需要特别注意,在使用$set时,需要传递的参数有三个 vm.$set(target,key,value),target不能是Vue.js实例或者vue.js实例的根数据对象,所谓的根数据对象是指vm.$data *

(2)数组的监听

vue通过拦截数组原型的方式实现数组的变化的监听,所以有些不是数组原型定义的方法进行的数组操作,发生的变化,是数组感知不到的,比如通过数组下标修改对应位置的值(this.list[0] = 2),或者通过数组长度改变数组(清空数组的操作: this.list.length = 0 )。

所以进行数组操作的时候,尽量使用数组原型方法操作:push shift unshift pop splice sort reverse 等方法

文章来源:https://blog.csdn.net/weixin_43502666/article/details/135358982
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。