【无标题】Vue2实现响应式的原理

Vue2通过Object.defineProperty实现响应式,主要针对对象和数组,但存在无法检测属性新增和删除的问题。为解决这些问题,Vue3引入了Proxy,它能更细粒度地监听数据变化,支持属性动态添加和删除,提高了性能和灵活性。
摘要由CSDN通过智能技术生成

Vue2实现响应式核心就是Object.defineProperty数据劫持,针对数组重写了数组方法
在Vue2源码中实现响应式考虑到更多情况,以下所写了V2实现响应式的核心逻辑

const data = {
  name: 'wft',
  age: 18,
  info: {
    test: '哈哈哈'
  },
  list: [1, 2, 3, 4, 5]
}

const oldArrProto = Array.prototype;
const newArrProto = Object.create(oldArrProto);
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {
  newArrProto[methodName] = function () {  // 1. 更新视图; 2. 执行原来的方法
    oldArrProto[methodName].call(this, ...arguments)
    console.log('更新视图操作----->>>')
  }
})

observer(data)

function observer(target) {
  if (typeof target !== 'object' || target === null) {
    return target
  }

  if (target.constructor === Array) {  //  如果是数组的话, 就把原型对象修改成重写之后的(主要是为了能够进行更新视图操作)
    target.__proto__ = newArrProto
  }

  for (let key in target) {
    defineReactive(target, key, target[key])
  }
}

function defineReactive(target, key, value) {
  if (typeof value === 'object') {  // 多层嵌套递归
    observer(value)
  }
  Object.defineProperty(target, key, {
    get() {
      return value
    },
    set(newValue) {
      if (typeof newValue === 'object') {
        observer(newValue)
      }
      if (newValue !== value) {
        value = newValue
        console.log('更新视图操作----->>>')
      }
    }
  })
}

// data.name = '哈哈哈'
// data.info.test = '1111'
// data.name = {
//   name1: 'name1',
//   name2: 'name2'
// }

// data.name.name1 = '修改name1'
data.list.push(555)

上面有用到Object.create() ,这个方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__,是为了重写数组上的方法

当我们在data中定义了数据之后,vue2就会自动把它加入到响应式系统中(有对象就深层递归),而且Object.defineProperty能力有限,不能察觉到对象的属性新增(v2中我们使用Vue.set解决),也不能察觉到对象的属性删除(v2中我们使用Vue.delete解决),这些也都是Vue2中的缺点,性能损耗较大

但是Vue3中就很好的避免上述Vue2中的问题,v3是通过proxy代理来实现数据的响应式,并且是当我们真正用到的时候才会将其加入到响应式,并且支持属性的新增和删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值