Vue2不能检测哪些变化?为什么?

Vue2使用Object.defineProperty()来劫持数据,但无法直接检测数组元素和对象属性的新增或删除。为解决这个问题,Vue2重写了数组方法,如push、unshift等,因为直接修改数组元素可能不会触发setter,导致视图不更新。这样做是因为数组操作可能涉及多个索引的变动,需要遍历更新,可能影响性能。
摘要由CSDN通过智能技术生成

vue2不能检测哪些变化?

1.数组元素的增改

2.对象的增删

data(){
    return{
        arr:[1,2,3];
        obj:{a:1,b:2,c:3};
    }
}

//this.arr[3] = 4;//数据更改为[1,2,3,4],view视图并未更改
//this.arr[0] = 0;//数据更改为[0,2,3],view视图并未更改
//this.obj.d = 4; //数据更改为{a:1,b:2,c:3,d:4},view视图并未更改
//delete this.obj.a; //数据更改为{b:2,c:3},view视图并未更改
vue2采用Object.defineProperty()来劫持数据,Object.defineProperty()本身是能够检测到这些变化的,但是由于性能问题而没有采用;
在vue2源码里面为什么要重写数组方法,出于什么性能问题呢?
以下是对vue2劫持数据的模拟
function defineReactive(obj, key, value) {
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get() {
            console.log(`获取的key:${key},值:${value}`);
            return value;
        },
        set(newValue) {
            value = newValue;
            console.log(`设置的key:${key},值:${value}`);
        }
    })
}
function observe(data) {
    const keys = Object.keys(data)
    for (let i = 0; i < keys.length; i++) {
        const key = keys[i]
        defineReactive(data, key, data[key])
    }

}
var arrlist = ["张", "王", "李"]
observe(arrlist)

当我执行以下操作

//arrlist[0] = "徐";
控制台打印--设置的key:0,值:徐

//arrlist.push("赵");
没有触发get set

//arrlist.unshift("熊");
控制台打印
获取的key:2,值:李
获取的key:1,值:王
设置的key:2,值:王
获取的key:0,值:张
设置的key:1,值:张
设置的key:0,值:熊

总结:

Object.defineProperty只能检测对象初始时,已定义的key;对于数组,设置已监听数据的下标时,才会触发。数组push 一定不会触发get set,unshift shift pop可能会触发,比如不断进行pop操作数组为[],就不会再次触发,所以是可能;并不是Object.defineProperty监听不到数组的变更,而是对数组的每一次操作都可能会影响其他值索引的变更(对象则不会影响其他key),在多数情况下,需要重新遍历数组,重新检测,例如unshift操作,当数据特别多的时候非常浪费性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值