vueconf(2018hangzhou)大會剛剛過去,vue作者尤大大向我們展示了vue3.0的進展,並介紹vue3.0的一些改動,其中最令我期待的就是重寫資料監聽機制。
談起vue的雙向資料繫結,我們首先能想到的就是es5中object.defineproperty
,利用重寫屬性的get
、set
,我們可以完成資料劫持監聽,使用觀察者模式,在資料發生改變的時候,通知訂閱者更新狀態。
我們就針對observer
觀察者部分寫了乙個簡易的**如下:
function observer (data)
observer.prototype = )
},convert: function (key, val) ,
definereactive: function (data, key, val)
return val
},set: function (newval)
})}}
function observe (value, vm)
return new observer(value)
}複製**
以上**中我們定義了乙個observer
建構函式,即觀察者。利用object.defineproperty
我們將傳入物件的所有屬性(包含子屬性)全部進行資料監聽,並在get
方法中,在訂閱器裡新增一條訂閱。一旦某屬性發生改變,通知到訂閱器。
dep訂閱器,compile指令,watcher訂閱者的**就不再分析,mvvm的總體結構可以由下圖看出
整個過程是乙個觀察者、訂閱器、訂閱者、指令器四部分的事情,各司其職。
proxy是es6中新增的建構函式,它可以理解為在目標物件之前架設一層「攔截」,外界對該物件的訪問,都必須通過這層攔截,因此提供了一種機制,可以對外界的訪問進行過濾改寫。proxy原意是**,在這裡我們可以理解為「**」某些操作。
var obj = new proxy({}, `)
return reflect.get(target, key, receiver)
},set: function (target, key, value, receiver) `)
return reflect.set(target, key, value, receiver)
}})複製**
上面**對乙個空物件架設了一層攔截,我們可以在proxy的第二個引數中傳入乙個handler
物件,物件中可以定義攔截行為。
在get
和set
中,我們都用到了reflect
。reflect
物件與proxy
物件一樣,也是es6位了操作物件而提供的新api。reflect
物件的方法與proxy
物件的方法一一對應,比如proxy
方法攔截target
物件的屬性賦值行為。它採用reflect.set
方法將值賦值給物件的屬性,確保完成原有的行為,然後再部署額外的功能。
根據以上**我們寫一段測試**:
obj.text = 'hello world!'
// proxy set text
var _text = obj.text
// proxy get text
複製**
利用以上proxy
的一些特性,我們修改**如下:
function observe (value, vm)
let dep = new dep()
return new proxy(value,
return reflect.get(target, key, receiver)
},set: function (target, key, value, receiver)
})}複製**
我們將傳入的物件直接替換為proxy
物件,入參handler
的get
和set
中的新增訂閱者和通知訂閱器邏輯保持不變。
整個過程沒有做其他多餘的判斷,由於vue3.0還沒有發布,沒有實際原始碼可以借鑑,所以以上只是個人實現的簡單版本(完整**)。將整個mvvm運用到html中,以下是執行後的效果(沒做gif,湊合看吧):
放棄了object.defineproperty
,基於 proxy 觀察者機制以滿足全語言覆蓋及更好的效能。加上其它方法的優化改動,vue3.0可以提速一倍/記憶體使用降低一半;
observer
模組將可以單獨作為乙個庫來使用。
很遺憾的是,es6的proxy
無法被轉譯為es5,所以它將不被ie所支援。對於這個問題,vue3.0將給出ie11的相容方案,即在ie11下,還是使用的object.defineproperty
機制。
ecmascript 6 入門(阮一峰):es6.ruanyifeng.com/#docs/proxy
vue 3.0 更新計畫:更快,更小,讓開發者更輕鬆: www.oschina.net/news/101906…
為什麼proxy可以優化vue的資料監聽機制: juejin.im/post/5bfe33…
Vue MVVM框架實現原理
資料劫持 發布訂閱模式 遍歷data選項中的屬性,新增資料的觀測,執行observe的方法,使用object.defineproperty方法轉換為get和set方法,實現資料的劫持,並且新增乙個compiler方法,對每個元素節點進行判斷,如果是文字節點,根據指令模板去替換資料 當資料發生變化時,...
javascript實現proxy模式
script 模式 proxy 也是物件,他的目的就是為了節制 控制 對本體物件的訪問 extjs就採用了很多中 模式 圖書館 本體物件,例項化讀書館需要消耗很多的資源 var libraryinte ce new bh.inte ce libraryinte ce addbook findbook...
Proxy實現AOP切面程式設計
通過jdk的proxy 實現對業務類做簡單的aop實現 介面 userservice 包含的方法為切入點,會被 攔截 類 userserviceimpl 實現userservice介面 類 userservicefactory 工廠模式生成動態 類 myaspect 切面類,實現對切入點的操作 us...