什么是單項(xiàng)綁定茫陆、雙向綁定?
- 單項(xiàng)綁定(例:react):顧名思義,就是將model值綁定至視圖層惕耕,更新model時(shí)自動(dòng)更新視圖。
- 雙向綁定(例:vue):用戶在視圖層操作數(shù)據(jù)的同時(shí)罢荡,model也被更新了赡突。
粗略地看,雙向綁定免去了向model層插入數(shù)據(jù)的操作区赵,簡化了代碼惭缰,提升了開發(fā)效率。是的笼才,現(xiàn)在追求開發(fā)效率漱受,很多公司都在使用vue來開發(fā),v-model一加骡送,舍我其誰昂羡?(逃
原理
VUE中雙向綁定
vue2中使用Object.defineProperty()方法來進(jìn)行數(shù)據(jù)劫持以及發(fā)布者-訂閱模式來實(shí)現(xiàn)雙向綁定,數(shù)據(jù)劫持的時(shí)候會遍歷每個(gè)屬性摔踱,對每個(gè)屬性加上get虐先、set方法
實(shí)現(xiàn)原理就是
- 實(shí)現(xiàn)一個(gè)數(shù)據(jù)監(jiān)聽器Observer,能夠?qū)?shù)據(jù)對象的所有屬性進(jìn)行監(jiān)聽派敷,如有變動(dòng)可拿到最新值并通知訂閱者
- 實(shí)現(xiàn)一個(gè)指令解析器Compile蛹批,對每個(gè)元素節(jié)點(diǎn)的指令進(jìn)行掃描和解析,根據(jù)指令模板替換數(shù)據(jù)篮愉,以及綁定相應(yīng)的更新函數(shù)
- 實(shí)現(xiàn)一個(gè)Watcher腐芍,作為連接Observer和Compile的橋梁,能夠訂閱并收到每個(gè)屬性變動(dòng)的通知试躏,執(zhí)行指令綁定的相應(yīng)回調(diào)函數(shù)猪勇,從而更新視圖
-
mvvm入口函數(shù),整合以上三者
vue3中已經(jīng)將雙向綁定使用Proxy重寫颠蕴,解決了當(dāng)年vue2不能監(jiān)聽數(shù)組變化的苦惱泣刹,同時(shí)也提升了效率。
Proxy的劫持手段則是官宣標(biāo)準(zhǔn)——直接監(jiān)聽data的所有域值犀被,免去了Object.defineProperty循環(huán)遍歷才能劫持每一個(gè)屬性的hack项玛。
//data is our source object being observedconst
observer = new Proxy(data, {
get(obj, prop) { ... },
set(obj, prop, newVal) { ... },
deleteProperty() {
//invoked when property from source data object is deleted
}
})
Proxy構(gòu)造函數(shù)的第一個(gè)參數(shù)是原始數(shù)據(jù)data;第二個(gè)參數(shù)是一個(gè)叫handler的處理器對象弱判。Handler是一系列的代理方法集合襟沮,它的作用是攔截所有發(fā)生在data數(shù)據(jù)上的操作。這里的get()和set()是最常用的兩個(gè)方法,分別代理訪問和賦值兩個(gè)操作开伏。在Observer里膀跌,它們的作用是分別調(diào)用dep.depend()和dep.notify()實(shí)現(xiàn)訂閱和發(fā)布。直接反映在Vue里的好處就是:我們不再需要使用Vue.$set()這類響應(yīng)式操作了固灵。除此之外捅伤,handler共有十三種劫持方式,比如deleteProperty就是用于劫持域刪除巫玻。
React中的單項(xiàng)數(shù)據(jù)流
react中對數(shù)據(jù)的概念是:數(shù)據(jù)的流向只能通過props由外層到內(nèi)層 一層一層往里傳遞丛忆。
對于父子組件來說,父組件總是通過 Props 向子組件傳遞數(shù)據(jù)仍秤。所有的 prop 都使得其父子 prop 之間形成了一個(gè)單向下行綁定:父級prop 的更新會向下流動(dòng)到子組件中熄诡,但是反過來則不行。這樣會防止從子組件意外改變父級組件的狀態(tài)诗力,從而導(dǎo)致你的應(yīng)用的數(shù)據(jù)流向難以理解凰浮。
當(dāng)然,你在平時(shí)開發(fā)的時(shí)候真的是數(shù)據(jù)一層一層的從model流到layout到業(yè)務(wù)組件的嗎苇本?
那當(dāng)然肯定不是的袜茧,業(yè)務(wù)組件層級搞起來了,那還玩?zhèn)€錘子瓣窄?所以react加了個(gè)context這個(gè)東西笛厦,方便我們組件隔代通信。
優(yōu)缺點(diǎn)
相比于vue一個(gè):form="formData"俺夕,react每次表單操作都需要手動(dòng)更新state的值裳凸,這樣給人一種哆嗦的感覺,代碼書寫上 VUE win啥么。
但這里拋出一個(gè)問題:數(shù)據(jù)每次變化時(shí)登舞,視圖都要更新嗎贰逾?
單向數(shù)據(jù)流其實(shí)是沒有狀態(tài)的, 這使得單向綁定能夠避免狀態(tài)管理在復(fù)雜度上升時(shí)產(chǎn)生的各種問題, 程序的調(diào)試會變得相對容易悬荣。
雙向綁定就顯得復(fù)雜的很多,需要手動(dòng)處理狀態(tài)變化的邏輯, 例如子組件修改父組件疙剑,兄弟組件互相修改氯迂,使得程序復(fù)雜度上升, 難以調(diào)試, 當(dāng)業(yè)務(wù)邏輯復(fù)雜時(shí),就會無從下手言缤。