在vue2.x中数据的相应机制是使用的Object.defineProperty,但是在3.0转而使用更快的原生Proxy,

1、基于Object.defineProperty的实现存在的缺点:
Object.defineProperty需要遍历所有的属性,这就造成了如果vue对象的data/computed/props中的数据规模庞大,那么遍历起来就会慢很多。
同样,如果vue对象的data/computed/props中的数据规模庞大,那么Object.defineProperty需要监听所有的属性的变化,那么占用内存就会很大。
无法监听属性的添加删除、数组索引和长度的变更,
无法监听Class类型的数据
属性的新加或者删除也无法监听
不支持Map、Set、WeakMap和WeakSet
Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue 2.x里,是通过 递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象是才是更好的选择。

而proxy可以劫持整个对象,并返回一个新对象
并且有13种劫持操作
当然下面说的proxy也有缺点: 兼容性问题,对IE不够友好,所以vue3中采用的是如果是IE自动降级为Object.defaineProperty进行数据监听
2、Proxy

Proxy可以理解为在目标对象之前设置一层拦截,外接访问该对象的时候都必须通过这层拦截,可以对外界的访问进行过滤和改写。也就是进行代理
上代码,因为是和react同步进行的代码在一块稍微有点乱,谅解一下,感谢

 		let testObj = {
            a: 555
        }
        let proxyObj = new Proxy(this.state,{
            get: function(target,prop) {
                return prop in target ? target[prop] : 0   //一定要return
            },
            set: function(target,prop,value){
               /*  console.log(target, prop, value)
                console.log(target[prop]) */
                return target[prop] = value       //一定要return
            }
        })

        console.log(proxyObj.title); //es6学习
        console.log(proxyObj.title2);
        proxyObj.title = 'es6学习学习再学习';
       /*  this.setState({
            title: '学习react和es6'
        }) */
        console.log(proxyObj.title);
        // proxyObj.a = 8889999

当我们访问对象内原本存在属性的时候会返回原有属性对应的值,但是如果访问的属性不存在则会返回0
原生的语法:

let proxy = new Proxy(target, handler);

target是拦截的对象
handler也是一个对象用来定义拦截规则

以上是proxy的一个简单的介绍,有兴趣的可以去看看es6有关proxy的详细介绍
vue3使用proxy对整个数据进行监听,带来了初始化速度加倍的同时内存占用减半的效果

Logo

前往低代码交流专区

更多推荐