一 基于proxy的Observer
1 什么是proxy
Proxy 對象用于定義基本操作的自定義行為(如屬性查找剪勿、賦值脚翘、枚舉、函數(shù)調(diào)用等)兑牡。
proxy是es6新特性,為了對目標的作用主要是通過handler對象中的攔截方法攔截目標對象target的某些行為(如屬性查找税灌、賦值均函、枚舉、函數(shù)調(diào)用等)菱涤。
/* target: 目標對象苞也,待要使用 Proxy 包裝的目標對象(可以是任何類型的對象,包括原生數(shù)組粘秆,函數(shù)如迟,甚至另一個代理)。 /
/ handler: 一個通常以函數(shù)作為屬性的對象攻走,各屬性中的函數(shù)分別定義了在執(zhí)行各種操作時代理 proxy 的行為殷勘。 */
const proxy = new Proxy(target, handler);
2 為什么要用proxy,改用proxy之后的利與弊
** 3.0 將帶來一個基于 Proxy 的 observer 實現(xiàn)昔搂,它可以提供覆蓋語言 (JavaScript——譯注) 全范圍的響應式能力玲销,消除了當前 Vue 2 系列中基于 Object.defineProperty 所存在的一些局限,這些局限包括:1 對屬性的添加巩趁、刪除動作的監(jiān)測痒玩; 2 對數(shù)組基于下標的修改淳附、對于 .length 修改的監(jiān)測议慰; 3 對 Map、Set奴曙、WeakMap 和 WeakSet 的支持别凹;;
vue2.0 用 Object.defineProperty 作為響應式原理的實現(xiàn)洽糟,但是會有它的局限性炉菲,比如 無法監(jiān)聽數(shù)組基于下標的修改堕战,不支持 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 響應式?jīng)]用到的捕獲器(有興趣的同學可以研究一下)
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() -> 函數(shù)調(diào)用操作 的捕捉器军拟。
handler.construct() -> new 操作符 的捕捉器距贷。
① has捕獲器
has(target, propKey)
target:目標對象
propKey:待攔截屬性名
作用: 攔截判斷target對象是否含有屬性propKey的操作
攔截操作: propKey in proxy; 不包含for…in循環(huán)
對應Reflect: Reflect.has(target, propKey)
const he=new Proxy(data,{
//查詢數(shù)據(jù)
get(target,propName){
console.log("讀取p的${propName}屬性")
return target[propName]
},
//新增和修改數(shù)據(jù)
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響應式原理