一 基于proxy的Observer
1 什么是proxy
Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。
proxy是es6新特性,为了对目标的作用主要是通过handler对象中的拦截方法拦截目标对象target的某些行为(如属性查找、赋值、枚举、函数调用等)。
/* target: 目标对象,待要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。 /
/ handler: 一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 proxy 的行为。 */
const proxy = new Proxy(target, handler);
2 为什么要用proxy,改用proxy之后的利与弊
** 3.0 将带来一个基于 Proxy 的 observer 实现,它可以提供覆盖语言 (JavaScript——译注) 全范围的响应式能力,消除了当前 Vue 2 系列中基于 Object.defineProperty 所存在的一些局限,这些局限包括:1 对属性的添加、删除动作的监测; 2 对数组基于下标的修改、对于 .length 修改的监测; 3 对 Map、Set、WeakMap 和 WeakSet 的支持;;
vue2.0 用 Object.defineProperty 作为响应式原理的实现,但是会有它的局限性,比如 无法监听数组基于下标的修改,不支持 Map、Set、WeakMap 和 WeakSet等缺陷 ,所以改用了proxy解决了这些问题,这也意味着vue3.0将放弃对低版本浏览器的兼容(兼容版本ie11以上)。
3 proxy中hander对象的基本用法
vue3.0 响应式用到的捕获器(接下来会重点介绍)
handler.has() -> in 操作符 的捕捉器。 (vue3.0 用到)
handler.get() -> 属性读取 操作的捕捉器。 (vue3.0 用到)
handler.set() -> 属性设置* 操作的捕捉器。 (vue3.0 用到)
handler.deleteProperty() -> delete 操作符 的捕捉器。(vue3.0 用到)
handler.ownKeys() -> Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。(vue3.0 用到)
vue3.0 响应式没用到的捕获器(有兴趣的同学可以研究一下)
handler.getPrototypeOf() -> Object.getPrototypeOf 方法的捕捉器。
handler.setPrototypeOf() -> Object.setPrototypeOf 方法的捕捉器。
handler.isExtensible() -> Object.isExtensible 方法的捕捉器。
handler.preventExtensions() -> Object.preventExtensions 方法的捕捉器。
handler.getOwnPropertyDescriptor() -> Object.getOwnPropertyDescriptor 方法的捕捉器。
handler.defineProperty() -> Object.defineProperty 方法的捕捉器。
handler.apply() -> 函数调用操作 的捕捉器。
handler.construct() -> new 操作符 的捕捉器。
① has捕获器
has(target, propKey)
target:目标对象
propKey:待拦截属性名
作用: 拦截判断target对象是否含有属性propKey的操作
拦截操作: propKey in proxy; 不包含for…in循环
对应Reflect: Reflect.has(target, propKey)
const he=new Proxy(data,{
//查询数据
get(target,propName){
console.log("读取p的${propName}属性")
return target[propName]
},
//新增和修改数据
set(target,propName,value){
console.log("读取p的${propName}属性")
target[propName]=value
},
deleteProperty(target,propName){
console.log("读取p的${propName}属性")
return delete target[propName]
}
} )
② get捕获器
get(target, propKey, receiver)
target:目标对象
propKey:待拦截属性名
receiver: proxy实例
返回: 返回读取的属性
作用:拦截对象属性的读取
拦截操作:proxy[propKey]或者点运算符
对应Reflect: Reflect.get(target, propertyKey[, receiver])
③ set捕获器
set(target,propKey, value,receiver)
target:目标对象
propKey:待拦截属性名
value:新设置的属性值
receiver: proxy实例
返回:严格模式下返回true操作成功;否则失败,报错
作用: 拦截对象的属性赋值操作
拦截操作: proxy[propkey] = value
对应Reflect: Reflect.set(obj, prop, value, receiver)
④ deleteProperty 捕获器
deleteProperty(target, propKey)
target:目标对象
propKey:待拦截属性名
返回:严格模式下只有返回true, 否则报错
作用: 拦截删除target对象的propKey属性的操作
拦截操作: delete proxy[propKey]
对应Reflect: Reflect.delete(obj, prop)
(183条消息) vue3.0 响应式原理(超详细)_zl_Alien的博客-CSDN博客_vue3.0响应式原理