當(dāng)問及這個問題的時候精算,你可能首先就會想到vue的v-model线欲,然后官網(wǎng)是這么介紹的
那么如何自己實現(xiàn)一個v-model的這種雙向數(shù)據(jù)綁定的機(jī)制呢
請看下面代碼
這應(yīng)該是最簡單的實現(xiàn)v-model數(shù)據(jù)綁定的demo。只需要在一個組件里面有個props否过,加上一個value午笛,然后當(dāng)組件要去修改數(shù)據(jù)的時候, $emit一個input事件苗桂,并且把新的值傳出去药磺。這就實現(xiàn)了Vue里面的數(shù)據(jù)雙向綁定。
其實煤伟,v-model指令就是在組件上加了一個props与涡,以及增加了一個事件監(jiān)聽(比如本demo中的input事件),說白了持偏,在v-model里面作者幫我們封裝了這個雙向綁定的邏輯,我們只管拿去用就好氨肌。
一句話總結(jié)就是:在數(shù)據(jù)渲染時使用prop渲染數(shù)據(jù)
將prop綁定到子組件自身的數(shù)據(jù)上鸿秆,修改數(shù)據(jù)時更新自身數(shù)據(jù)來替代prop,
watch子組件自身數(shù)據(jù)的改變怎囚,觸發(fā)事件通知父組件更改綁定到prop的數(shù)據(jù)卿叽。
面試官可能還會不厭其煩地問你,Vue數(shù)據(jù)綁定這樣做的好處是什么恳守?
敲黑板劃重點:父組件數(shù)據(jù)改變時考婴,不會修改存儲prop的子組件數(shù)據(jù),只是以子組件數(shù)據(jù)為媒介催烘,完成對prop的雙向修改沥阱。
如果還要繼續(xù)深挖,就得搬個小板凳泡上一壺茶準(zhǔn)備好瓜子花生伊群,坐下來跟面試官好好聊一聊Vue的響應(yīng)式原理了考杉,Object.defineProperty()通過 getter 和 setter 劫持了對象賦值的過程策精,在這個過程中可以進(jìn)行更新 dom 操作等等。
vue.js 是采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式崇棠,通過Object.defineProperty()來劫持各個屬性的setter咽袜,getter,在數(shù)據(jù)變動時發(fā)布消息給訂閱者枕稀,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)询刹。
具體步驟:
第一步:需要observe的數(shù)據(jù)對象進(jìn)行遞歸遍歷,包括子屬性對象的屬性萎坷,都加上 setter和getter凹联。這樣的話,給這個對象的某個值賦值食铐,就會觸發(fā)setter匕垫,那么就能監(jiān)聽到了數(shù)據(jù)變化
第二步:compile解析模板指令,將模板中的變量替換成數(shù)據(jù)虐呻,然后初始化渲染頁面視圖象泵,并將每個指令對應(yīng)的節(jié)點綁定更新函數(shù),添加監(jiān)聽數(shù)據(jù)的訂閱者斟叼,一旦數(shù)據(jù)有變動偶惠,收到通知,更新視圖
第三步:Watcher訂閱者是Observer和Compile之間通信的橋梁朗涩,主要做的事情是:
1忽孽、在自身實例化時往屬性訂閱器(dep)里面添加自己
2、自身必須有一個update()方法
3谢床、待屬性變動dep.notice()通知時兄一,能調(diào)用自身的update()方法,并觸發(fā)Compile中綁定的回調(diào)识腿,則功成身退出革。
第四步:MVVM作為數(shù)據(jù)綁定的入口,整合Observer渡讼、Compile和Watcher三者骂束,通過Observer來監(jiān)聽自己的model數(shù)據(jù)變化,通過Compile來解析編譯模板指令成箫,最終利用Watcher搭起Observer和Compile之間的通信橋梁展箱,達(dá)到數(shù)據(jù)變化 -> 視圖更新;視圖交互變化(input) -> 數(shù)據(jù)model變更的雙向綁定效果蹬昌。