proxy与defineProperty

vue2采用defineProperty定义响应式对象 不支持IE8以下

vue3采用proxy定义响应式对象 es6新语法 不支持IE

proxy相较于defineProperty有如下优点。

Proxy是对整个对象的代理,而Object.defineProperty只能代理某个属性。

对象上新增属性,Proxy可以监听到,Object.defineProperty不能。

数组新增修改,Proxy可以监听到,Object.defineProperty不能。

若对象内部属性要全部递归代理,Proxy可以只在调用的时候递归,而Object.definePropery需要一次完成所有递归,性能比Proxy差。

Proxy不兼容IE,Object.defineProperty不兼容IE8及以下

Proxy使用上比Object.defineProperty方便多。

思考:因此vue2 当对对象的属性进行新增的时候,需要使用vue.set对新增对象进行响应式的设置,而vue3就不用。

vue3里面

数组被替换emptyArray.value = [],常规写法,这样可以检测到变化
watch(emptyArray, () => {//这里使用emptyArray.value是监测不到被替换的console.log('空数组长度变化了')}) 
使用数组的变更方法(emptyArray.value.push(1)),
watch(emptyArray, () => {//必须使用deep才能检测到使用数组变化变更方法的改变,但是这些改变可以引起UI的改变console.log('空数组长度变化了')},{
 deep:true}) 

总结:ref数组地址变化的时候,才会被监听到。

因为vue3源码里dowatch方法,比较新值与旧值是否相同的时候采用的是object.is

 

Object.defineProperty(Object, 'is', {
  value: function(x, y) {
    if (x === y) {
      // 针对+0 不等于 -0的情况
      return x !== 0 || 1 / x === 1 / y;
    }
    // 针对NaN的情况
    return x !== x && y !== y;
  },
  configurable: true,
  enumerable: false,
  writable: true
});

Object.is比较引用类型的时候,比较的是地址。

所以ref的array需要采用=赋值的方式改变其地址,让watch再不需要deep的时候被监听到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值