免費(fèi)自己創(chuàng)建個(gè)人網(wǎng)站營(yíng)銷型網(wǎng)站建設(shè)套餐
Vue2 雙向綁定原理
mvvm 雙向綁定,采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式,通過(guò) Object.defineProperty() 來(lái) 劫持各個(gè)屬性的 setter、getter,在數(shù)據(jù)變動(dòng)時(shí)發(fā)布消息給訂閱者,觸發(fā)相應(yīng)的監(jiān)聽(tīng)回調(diào)。

幾個(gè)要點(diǎn): 1)實(shí)現(xiàn)一個(gè)數(shù)據(jù)監(jiān)聽(tīng)器 Observer,能夠?qū)?shù)據(jù)對(duì)象的所有屬性進(jìn)行監(jiān)聽(tīng),如有變動(dòng)可拿到最新值并通 知訂閱者 2)實(shí)現(xiàn)一個(gè)指令解析器 Compile,對(duì)每個(gè)元素節(jié)點(diǎn)的指令進(jìn)行掃描和解析,根據(jù)指令模板替換數(shù)據(jù), 以及綁定相應(yīng)的更新函數(shù) 3)實(shí)現(xiàn)一個(gè) Watcher,作為連接 Observer 和 Compile 的橋梁,能夠訂閱并收到每個(gè)屬性變動(dòng)的通 知,執(zhí)行指令綁定的相應(yīng)回調(diào)函數(shù),從而更新視圖 4)mvvm 入口函數(shù),整合以上三者
具體步驟: 需要 observe 的數(shù)據(jù)對(duì)象進(jìn)行遞歸遍歷,包括子屬性對(duì)象的屬性,都加上 setter 和 getter這樣的 話,給這個(gè)對(duì)象的某個(gè)值賦值,就會(huì)觸發(fā) setter,那么就能監(jiān)聽(tīng)到了數(shù)據(jù)變化 compile 解析模板指令,將模板中的變量替換成數(shù)據(jù),然后初始化渲染頁(yè)面視圖,并將每個(gè)指令對(duì) 應(yīng)的節(jié)點(diǎn)綁定更新函數(shù),添加監(jiān)聽(tīng)數(shù)據(jù)的訂閱者,一旦數(shù)據(jù)有變動(dòng),收到通知,更新視圖 Watcher 訂閱者是 Observer 和 Compile 之間通信的橋梁,主要做的事情是:在自身實(shí)例化時(shí)往屬 性訂閱器(dep)里面添加自己自身必須有一個(gè) update() 方法待屬性變動(dòng) dep.notice() 通知時(shí),能調(diào) 用自身的 update() 方法,并觸發(fā) Compile 中綁定的回調(diào),則功成身退。 MVVM 作為數(shù)據(jù)綁定的入口,整合 Observer、Compile 和 Watcher 三者,通過(guò)Observer來(lái)監(jiān)聽(tīng) 自己的 model 數(shù)據(jù)變化,通過(guò) Compile 來(lái)解析編譯模板指令,最終利用 Watcher 搭起 Observer 和 Compile 之間的通信橋梁,達(dá)到數(shù)據(jù)變化 -> 視圖更新;視圖交互變化(input) -> 數(shù)據(jù) model 變 更的雙向綁定效果
Vue3 雙向綁定原理
用Proxy代替Object.defineProperty?
Vue2.X通過(guò)Object.defineProperty()來(lái)劫持各個(gè)屬性的setter,getter,新版本通過(guò)Proxy劫持屬性 Proxy優(yōu)勢(shì) 支持?jǐn)?shù)組,其實(shí)還不止
Object.defineProperty() 的問(wèn)題主要有三個(gè): 不能監(jiān)聽(tīng)數(shù)組的變化 必須遍歷對(duì)象的每個(gè)屬性 必須深層遍歷嵌套的對(duì)象
1,Object.definedProperty作用是劫持一個(gè)對(duì)象的屬性,劫持屬性的getter和setter方法,在對(duì)象的屬性發(fā)生變化時(shí)進(jìn)行特定的操作。而 Proxy 劫持的是整個(gè)對(duì)象。
Proxy 會(huì)返回一個(gè)代理對(duì)象,我們只需要操作新對(duì)象即可,而 Object.defineProperty只能遍歷對(duì)象屬性直接修改。
2,Object.definedProperty不支持?jǐn)?shù)組,更準(zhǔn)確的說(shuō)是不支持?jǐn)?shù)組的各種API,因?yàn)槿绻麅H僅考慮arry[i] = value 這種情況,是可以劫持的,但是這種劫持意義不大。而Proxy 可以支持?jǐn)?shù)組的各種API。
3,盡管 Object.defineProperty 有諸多缺陷,但是其兼容性要好于 Proxy.
PS: Vue2.x 使用 Object.defineProperty 實(shí)現(xiàn)數(shù)據(jù)雙向綁定,V3.0 則使用了 Proxy