vue2利用object.defineproperty來劫持data資料的getter和setter操作,遇到陣列和物件必須迴圈遍歷所有的域值才能劫持每乙個屬性 。
object.keys(data).foreach((prop) => ,缺點:1、 無法檢測到物件屬性的新增或刪除 ,需要使用 set 等其他方法。set (newval)
});});
2、 不能監聽陣列的變化 ,侷限於陣列的push/pop/shift/unshift/splice/sort/reverse
七個方法
而更快的es6中的原生proxy就能解決這些問題,為什麼vue3才使用 proxy ,原因還是瀏覽器相容所限。至今ie仍不支援proxy,所以vue3還是為原始瀏覽器保留了object.defineproperty
的實現。
mdn :proxy`物件用於定義基本操作的自定義行為(如屬性查詢,賦值,列舉,函式呼叫等)
可以理解為在目標物件之前做一層攔截,外部所有的訪問都必須通過這層攔截,通過這層攔截可以做很多事情,比如對資料進行過濾、修改或者收集資訊之類。
let obj =proxy建構函式的第乙個引數是原始資料data;第二個引數是乙個叫handler的處理器物件。handler是一系列的**方法集合,它的作用是攔截所有發生在data資料上的操作。這裡的get()和set()是最常用的兩個方法,分別**訪問和賦值兩個操作。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
const list = [1, 2];const observer = new proxy(list, is changed!`);
return reflect.set(...arguments);
},});
observer.push(3);
observer[3] = 4;
let handler =proxy**目標物件,每個攔截方式與es6提供的另乙個apireflect的13種靜態方法一一對應。二者一般是配合使用的,在修改proxy**物件時,一般也需要同步到**的目標物件上,這個同步就是用reflect對應方法來完成的。例如上面的reflect.set(target, key, value)同步目標物件屬性的修改。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' // 支援陣列內容變化
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框架出發,探索其中資料劫持的奧秘 本文所選取的...