美文网首页
vue2和vue3的响应式原理

vue2和vue3的响应式原理

作者: 梁帆 | 来源:发表于2022-05-26 13:18 被阅读0次

一、vue2响应式

1.实现原理

(1)对象类型

通过

Object.defineProperty()

对属性的读取、修改进行拦截(数据劫持)。

(2)数据类型

通过重写更新数组的一系列方法来实现拦截(对数组的变更方法进行了包裹)。

Object.defineProperty(data, 'count', {
  get() {},
  set() {}
})

2.模拟vue2中实现响应式

let person = {
  name: 'Tom',
  age: 18
}
let p = {}
Object.defineProperty(p, 'name', {
  configurable: true,    // 配置可被删除和新增(无法响应)
  // 读取
  get() {
    console.log('读取操作响应')
    return person.name
  },
  // 修改
  set(value) {
    console.log('修改操作响应')
    person.name = value
  }
})
Object.defineProperty(p, 'age', {
 // 与上文name属性类似,这里省略
 ......
})

3.存在的问题

①新增属性、删除属性,界面不会更新。
②直接通过下标修改数组,界面不会自动更新。

二、vue3响应式

1.实现原理

(1)通过Proxy(代理)

通过Proxy拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等。

(2)通过Reflect(反射)

通过Reflect对被代理对象的属性进行操作

2.模拟vue3中实现响应式

用到了Proxy代理对象和Reflect反射对象。

let person = {
  name: 'Tom',
  age: 18
}
// 让p映射对person的操作
const p = new Proxy(person, {
  // 读取、新增
  get(target, propName) {
    console.log('读取或新增操作响应')
    // return target[propName]
    return Reflect.get(target, propName)
  }
  // 修改
  set(target, propName, value) {
    console.log('修改操作响应')
    // target[propName] = value
    Reflect.set(target, propName, value)
  }
  // 删除
  deleteProperty(target, propName) {
    console.log('删除操作响应')
    // return delete target[propName]
    return Reflect.deleteProperty(target, propName)
  }
})

这个示例中,我们在Reflect对象之上有一行被注释的代码,这里没有用到Reflect,这样做更符合我们的直觉和常规用法,但是缺点就是不好捕获错误,得用到try-catch,这样铺列开来,就让底层源码有一堆的try-catch。用了Reflect对象来处理,就可以让封装框架更加健壮。

相关文章

网友评论

      本文标题:vue2和vue3的响应式原理

      本文链接:https://www.haomeiwen.com/subject/xhglqrtx.html