摘要:數據劫持數據劫持即使用實現了的雙向綁定。不輸出內容數據代理即代理的意思。的攔截處理器除了外還支持多種攔截方式,具體請查閱官方文檔嵌套查詢。實際上也是不支持嵌套查詢的。
數據劫持
數據劫持即使用Object.defineProperty()實現了vue的雙向綁定。先來看看它是如何實現的
let obj = {}, txt = "" Object.defineProperty(obj,"txt",{ set(val) { console.log("set ....") txt = val || ""; }, get() { //獲取obj.txt時會觸發get的回調。 console.log("get ....") return txt } })
Object.defineProperty的缺點
1、無法監聽到數組的變化
舉個例子
//當被監聽的屬性是數組時 let arr = [1,2,3] let obj = {} Object.defineProperty(obj,"arr",{ set(val) { console.log("set",val) arr = val }, get() { console.log("get") return arr } }) obj.arr.push(4) // get 實際上是改變arr的值但是卻沒有執行set而是執行了get obj.arr = [1,2,3,4] // 執行了set
當被監聽的屬性是數組,這幾個方法push、pop、shift、unshift、splice、sort、reverse不會觸發set。vue將這幾個修改原始的數組的方法稱為變異方法
2、必須遍歷對象的每一個屬性
Object.keys(obj).forEach(key=>{ Object.defineProperty(obj,key,{ //.... }) })
3、必須深層遍歷嵌套對象
let person = { name:{ firstName:"chan", lastName:"louis" } }當遇到變異方法時舊版本的vue通過重寫方法來進行數據劫持
const aryMethods = ["push", "pop", "shift", "unshift", "splice", "sort", "reverse"]; const arrayAugmentations = []; aryMethods.forEach((method)=> { // 這里是原生 Array 的原型方法 let original = Array.prototype[method]; // 將 push, pop 等封裝好的方法定義在對象 arrayAugmentations 的屬性上 // 注意:是實例屬性而非原型屬性 arrayAugmentations[method] = function () { console.log("has change"); // 調用對應的原生方法并返回結果 return original.apply(this, arguments); }; }); let list = ["a", "b", "c"]; // 將我們要監聽的數組的原型指針指向上面定義的空數組對象 // 這樣就能在調用 push, pop 這些方法時走進我們剛定義的方法,多了一句 console.log list.__proto__ = arrayAugmentations; list.push("d"); // 我被改變啦! // 這個 list2 是個普通的數組,所以調用 push 不會走到我們的方法里面。 let list2 = ["a", "b", "c"]; list2.push("d"); // 不輸出內容Proxy數據代理
proxy即代理的意思。個人理解,建立一個proxy代理對象(Proxy的實例),接受你要監聽的對象和監聽它的handle兩個參數。當你要監聽的對象發生任何改變,都會被proxy代理攔截來滿足需求。
var arr = [1,2,3] var handle = { //target目標對象 key屬性名 receiver實際接受的對象 get(target,key,receiver) { console.log(`get ${key}`) // Reflect相當于映射到目標對象上 return Reflect.get(target,key,receiver) }, set(target,key,value,receiver) { console.log(`set ${key}`) return Reflect.set(target,key,value,receiver) } } //arr要攔截的對象,handle定義攔截行為 var proxy = new Proxy(arr,handle) proxy.push(4) //可以翻到控制臺測試一下會打印出什么
1、使用proxy可以解決defineProperty不能監聽數組的問題,避免重寫數組方法;
2、不需要再遍歷key。
3、Proxy handle的攔截處理器除了get、set外還支持多種攔截方式,具體請查閱官方文檔(https://developer.mozilla.org...)
4、嵌套查詢。實際上proxy get()也是不支持嵌套查詢的。解決方法:
let handler = { get (target, key, receiver) { // 遞歸創建并返回 if (typeof target[key] === "object" && target[key] !== null) { return new Proxy(target[key], handler) } return Reflect.get(target, key, receiver) } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105370.html
摘要:我們先以框架出發,探索其中數據劫持的奧秘。針對對象在數據劫持這個問題上,可以被認為是的升級版。技術支持監測數組的等方法操作,支持對象屬性的動態添加和刪除,極大的簡化了響應化的代碼量。 隨著前端界的空前繁榮,各種框架橫空出世,包括各類mvvm框架百家爭鳴,比如Anglar、Vue、React等等,它們最大的優點就是可以實現數據綁定,再也不需要手動進行DOM操作了,它們實現的原理也基本上是...
摘要:攔截之前的準備在應用啟動的特定生命周期內改寫字節碼,植入特定的邏輯處理代碼進行攔截。劫持通過字節碼改寫動態代理等技術,在客戶端調用代碼中嵌入特定處理邏輯,獲取調用相關的信息,如調用地址調用協議調用結果等。 這次我們為大家帶來中間件增強框架專題(MOF)的最后一篇文章,為大家講解MOF中的InterceptFramework框架。該框架可以在應用啟動過程中獲取畫像信息,實現應用畫像數據采...
摘要:只能劫持對象的屬性因此我們需要對每個對象的每個屬性進行遍歷。屬性對于怎么拼接到和上面說到了怎么使用做數據劫持,怎么結合訂閱發布,請結合數據雙向綁定探究對照著數據劫持的部分去替換看一下。 前言 2018年11月16日,關注vue的人都知道這個時間點發生了什么事兒吧。vue3.0更新內容 研究數據雙向綁定的大佬們都在開始猜測這個新機制了,用原生Proxy替換Object.definePro...
摘要:方法實現將所有屬性掛載在觀察對象,將每一項做一個數據劫持就是將中每一項用定義新屬性并返回這個對象。當和發生變化時,自動會觸發視圖更新,獲取得到的也就是最新值。 MVVM及Vue實現原理 Github源碼地址:https://github.com/wyj2443573... mvvm 雙向數據綁定數據影響視圖,視圖影響數據angular 臟值檢測 vue數據劫持+發布訂閱模式vue 不...
閱讀 1698·2023-04-26 01:02
閱讀 4841·2021-11-24 09:39
閱讀 1803·2019-08-30 15:44
閱讀 2874·2019-08-30 11:10
閱讀 1783·2019-08-30 10:49
閱讀 984·2019-08-29 17:06
閱讀 609·2019-08-29 16:15
閱讀 902·2019-08-29 15:17