# 响应式原理
# Vue2.x实现
- 对象类型:通过
Object.defineProperty
对属性的读取、修改进行拦截(数据劫持) - 数组类型:通过重写数组的一系列方法实现拦截
Object.defineProperty(data,'xxx属性',{
get(){},
set(){}
})
TIP
- 存在问题:新增属性(新增响应式数据)、删除属性, 界面不会更新。
-备注:可以通过
$set
和$delete
解决 - 直接通过下标修改数组, 界面不会自动更新。
-备注:可以通过
$set
或者splice
替换的方法解决
# Vue3.x实现
proxy:是ES6一个新增特性。Proxy有两个参数一个是原始的对象 一个是用来定制拦截的行为(捕获器)。
- 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等
- 通过Reflect(反射): 对源对象的属性进行操作。
new Proxy(data, {
// 拦截读取属性值
get (target, prop) { // 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)
}
})
为什么要使用Reflect而不直接使用target[prop]
?
Reflect
会有一个返回值true或false,如果成功返回true,失败返回false,这样在底层编写代码的时候减少try,catch
的使用。
← toRefs函数 computed() →