vue2的响应式:
- 核心:
- 对象: 通过defineProperty对对象的已有属性值的读取和修改进行劫持(监视/拦截)
- 数组: 通过重写数组更新数组一系列更新元素的方法来实现元素修改的劫持
Object.defineProperty(data, 'count', {
get () {},
set () {}
})
- 问题
- 对象直接新添加的属性或删除已有属性, 界面不会自动更新
- 直接通过下标替换元素或更新length, 界面不会自动更新 arr[1] = {}
- 每个对象都要加上get和set方法,如果对象很多会导致效率很慢
vue3的响应式
- 核心:
- 通过Proxy(代理): 拦截对data任意属性的任意(13种)操作, 包括属性值的读写, 属性的添加, 属性的删除等...
- 通过 Reflect(反射): 动态对被代理对象的相应属性进行特定的操作
- 文档:
把目标对象变成代理对象 1.参数 user ====> target 目标对象
2.参数 handler ====> 处理器对象 用来监视数据 及数据的操作
new Proxy(data, {
// 拦截读取属性值
get (target, prop) {
return Reflect.get(target, prop)
},
// 拦截设置属性值或添加新属性
set (target, prop, value) {
return Reflect.set(target, prop, value)
},
// 拦截删除属性
deleteProperty (target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
proxy.name = 'tom'
总结:通过Proxy和 Reflect 共同去监听和修改以及为对象添加和删除属性的。
每个处理对象中的捕获器都有一个对应的Reflect方法,比如get
捕获器对应着Reflect.get
,对于这种行为,换句话说Proxy
与Reflect
总是这么的协同工作