Vue3 0beta 新資料劫持 Proxy

2021-10-06 02:29:45 字數 2566 閱讀 9849

vue2利用object.defineproperty來劫持data資料的getter和setter操作,遇到陣列和物件必須迴圈遍歷所有的域值才能劫持每乙個屬性 。

object.keys(data).foreach((prop) => ,

set (newval)

});});

缺點:1、 無法檢測到物件屬性的新增或刪除 ,需要使用 set 等其他方法。

2、 不能監聽陣列的變化 ,侷限於陣列的push/pop/shift/unshift/splice/sort/reverse七個方法

而更快的es6中的原生proxy就能解決這些問題,為什麼vue3才使用 proxy ,原因還是瀏覽器相容所限。至今ie仍不支援proxy,所以vue3還是為原始瀏覽器保留了object.defineproperty的實現。

mdn :proxy`物件用於定義基本操作的自定義行為(如屬性查詢,賦值,列舉,函式呼叫等)

可以理解為在目標物件之前做一層攔截,外部所有的訪問都必須通過這層攔截,通過這層攔截可以做很多事情,比如對資料進行過濾、修改或者收集資訊之類。

let obj = 

let proxyobj = new proxy(obj,,

set : function (target,prop,value)

})console.log(proxyobj.a);       // 1

console.log(proxyobj.b);       // 0

​   proxyobj.a = 666;

console.log(proxyobj.a)         // 888

proxy建構函式的第乙個引數是原始資料data;第二個引數是乙個叫handler的處理器物件。handler是一系列的**方法集合,它的作用是攔截所有發生在data資料上的操作。這裡的get()和set()是最常用的兩個方法,分別**訪問賦值兩個操作。

const list = [1, 2];

​const observer = new proxy(list, is changed!`);

return reflect.set(...arguments);

},});​

observer.push(3);

observer[3] = 4;

let handler = 

collectdeps() // 收集依賴

return reflect.get(target, key)

}, set(target, key, value)

}let proxy = new proxy(data, handler);

proxy.age = 18 // 支援新增屬性

let proxy1 = new proxy(, handler);

proxy1.arr[0] = 'proxy' // 支援陣列內容變化

proxy**目標物件,每個攔截方式與es6提供的另乙個apireflect的13種靜態方法一一對應。二者一般是配合使用的,在修改proxy**物件時,一般也需要同步到**的目標物件上,這個同步就是用reflect對應方法來完成的。例如上面的reflect.set(target, key, value)同步目標物件屬性的修改。

trap

描述handler.get

獲取物件的屬性時攔截

handler.set

設定物件的屬性時攔截

handler.has

攔截propname in proxy的操作,返回boolean

handler.construct

攔截proxy作為構造函式呼叫的操作

handler.ownkeys

攔截獲取proxy例項屬性的操作,包括object.getownpropertynames、object.getownpropertysymbols、object.keys、for...in

handler.deleteproperty

攔截delete proxy[propname]操作

handler.defineproperty

攔截objecet.defineproperty

handler.i***tensible

攔截object.i***tensible操作

handler.preventextensions

攔截object.preventextensions操作

handler.getprototypeof

攔截object.getprototypeof操作

handler.setprototypeof

攔截object.setprototypeof操作

handler.getownpropertydescriptor

攔截object.getownpropertydescriptor操作

1、 vue3的資料響應

2、 獲取屬性對應的值,無該屬性或者屬性為空返回預設值

3、 實現陣列負數索引的訪問

4、快取

5、隱藏屬性

6、唯讀檢視

vue 資料劫持

其實,並沒有這麼 神奇 的事,資料劫持的核心就是在 物件的身上重新定義被 物件所有可列舉屬性,並設定 getter 和 setter 監視著它的變化,然而實現這個核心功能就是乙個方法 object.defineproperty 通過該方法在例項物件上重新定義了和data物件裡面的所有屬性,然而就實現...

vue中的資料劫持

在瀏覽一篇博文的時候,看到裡面提到了vue中資料劫持的概念,之前只是知道有這個東西,知道這個東西是vue的核心之一,是實現資料雙向繫結的重要原理,但並未深入研究,那麼今天就借這篇文章學習整理一下vue中的資料劫持到底是什麼。在面經中最常見的問題之一就是,你知道雙向繫結嗎,知道什麼是mvvm嗎?學術性...

Vue核心之資料劫持

當前前端界空前繁榮,各種框架橫空出世,包括各類mvvm框架橫行霸道,比如anglar,regular,vue,react等等,它們最大的優點就是可以實現資料繫結,再也不需要手動進行dom操作了,它們實現的原理也基本上是髒檢查或資料劫持。那麼本文就以vue框架出發,探索其中資料劫持的奧秘 本文所選取的...